program Portal;
uses keys;
uses connect;
uses array2d;
uses jsr75i;
uses canvas;
uses alpha;
uses adata;
uses beta;
uses m2;
uses gfx;
uses sensor;
const
shoot=42;
dbg=0;
var
tile: array[0..93] of image; //все текстуры
chell: array[0..30] of image; //оригинал - 21
dialogbg: array[0..4] of image;
menubg,alphabg,sbutt: image;
bit: array[0..7,0..10] of integer; //анимация частиц
sipl,ntext: array[0..30] of integer; //правка анимации,т.метки
dmx,dmy,vr: array[0..3] of integer; //камера
px,py,spx,spy,metx,mety: array[0..2] of integer; //порталы
tmp: array[0..5] of integer; //для данных порталов
layer: array[0..3] of integer; //кол-во картинок в слое
tgame,tauthor: array[0..20] of string; //текст в игре
tmenu: array[0..9] of string; //текст менюшек
h,w,ht,wt,h2,w2,ha,ha2,hd: integer; //размер экрана
i,i2,i3,i4,i5,i6: integer; //универсальные переменные
k,key,key2,lsoft,rsoft: integer; //зажатие,нажатие,софты
k_up,k_down,k_left,k_right: integer; //2 тип управления
touch,ox,oy,bh: integer; //сенсор
test,txt: resource; //карта, помощь
mapx,mapy,layers,byte: integer; //размер карты
allmapx,allmapy,spawnx,spawny: integer;
x,y,iner,usk,jspeed: real; //физика игрока
jump: integer;
cr,vcr,vcr2,tcr: integer; //кадр,вариация,счетчик анимации
runcr,stopcr,upcr,downcr,aircr,dragcr: array [0..1] of integer;
tx,ty,sb,scx,scy,scx2,scy2: integer;
savtime,n,page,deffps: integer; //FPS
r,pox,poy,pwall,ix,iy,ang,ang2,sng: integer; //стрельба
bt: array[0..3] of boolean; //состояния частиц
click,max,txx,txy,wat,wat2,txs: integer; //текст
ts,paused,ported,aimmode,viewmode,menubits,
izometry,anim,yousure: boolean;
anim1,anim2: integer; //анимация объектов
viewtext,albg: integer;
pos,im,im2,come,ledit: integer; //меню
path,name,url,sort,nn: string; //редактор
ex,ey,er,efx,efy,elm,elx,ely: integer;
eok,efill,elink: boolean;
elar: array[0..2] of integer;
clicked,con,cback: command; //текстбокс
t1,t2: integer; //temp
conn: http; //онлайн-карты
rms: recordstore; //см. GameLoader
map,texts,ctext,len: integer;
tsize,plh,plw,anims: integer;
maps,clvl,music,delayfps,keystype,graphic: integer;
awind,animpack,texturepack,levelpack: integer; //прозрачность
modset,stemp,s: string;
lastSavedTime,n2,kolvofps:integer;

procedure Game; forward;
function win2utf(s: string): string;
begin
stemp:='';
i3:=Length(s)-1;
for i2:=0 to i3 do begin i4:=ord(GetChar(s,i2));
if i4>122 then stemp:=stemp+chr(i4+1104)
else stemp:=stemp+chr(i4);
end;
win2utf:=stemp;
end;


Function DLT3 (start: integer): integer;
begin
i:=start;
len:=Length(stemp);
i4:=i;
while (getStringWidth(copy(stemp,start,i))<w-wat2)
and (i<len) and (GetChar(stemp,i)<>nn) do begin
if GetChar(stemp,i)=' ' then i4:=i;
i:=i+1;
end;
if (i4<>i) and (GetChar(stemp,i)<>nn) then begin
i3:=i4;
repeat
i3:=i3+1;
until (GetChar(stemp,i3)=nn) or (GetChar(stemp,i3)=' ') or (i3>len);
if i3<len then if getStringWidth(Copy(stemp,i4,i3))<w-wat2 then i:=i4;
end;
if GetChar(stemp,i)=' ' then i:=i+1;
if GetChar(stemp,i)=nn then i:=i+1;
DLT3:=i;
end;


Procedure Format;
begin //разбивка строк
max:=0;
If getStringWidth(stemp)<w then begin
adata.init(2);
additem(2,stemp);
max:=1;
end;
else begin
i5:=0; //start
wat2:=0;
//for i2:=0 to 99 do begin
i2:=0;
repeat
if (i2 mod (hd/ha))=hd/ha-1 then wat2:=wat+ha else wat2:=0;
if i2=0 then adata.init(2);
i2:=i2+1;
additem(2,'');
i6:=DLT3(i5);
if GetChar(stemp,i6-1)<>nn then setitem(2,max,Copy(stemp,i5,i6))
else setitem(2,max,Copy(stemp,i5,i6-1));
if getitem(2,max)=nn then setitem(2,max,'');
if i5<>i6 then max:=max+1 else break;
i5:=i6;
until false;
//end;

end;
end;


procedure Parse2(s,n: string);
begin
adata.init(0);
i2:=length(s);
i3:=0;
for i:=0 to i2 do begin
if getChar(s,i)=n then begin
if (i>0) and (i<i2) then additem(0,copy(s,i3,i));
i3:=i+1;
end;
if i=i2 then additem(0,copy(s,i3,i));
end;

{init(0);
i2:=length(s)-1;
for i:=0 to i2 do begin
if getChar(s,i)=n then begin
if i>0 then additem(0,copy(s,0,i));
if i<>i2 then s:=copy(s,i+1,i2);
else s:=copy(s,0,i2);
i2:=length(s)-1;
i:=0;
end;
end;}
end;


procedure Exit;
begin
path:=copy(path,0,length(path)-length(name));
rms:=OpenRecordStore('Data');
ModifyRecordStoreEntry(rms,path,3);
closeRecordStore(rms);
halt;
end;


procedure ArraysReset;
begin //объекты
//х*у,действия к объекту
for i:=5 to 8 do begin
if (i<>7) then begin
SetArr(i); //двери,кнопки,панель
if i=5 then i4:=2
else if i=8 then i4:=3
else i4:=4;
i2:=Dim(15,i4); //размер
i4:=i4-1;
for i3:=0 to 14 do
for i2:=0 to i4 do
PutInt(i3,i2,0);
//FillInt(0);
end;
end;

end;


procedure GameLoader;
begin
h:=GetHeight;
w:=GetWidth;
s:='Загрузка...';
setFont(0,0,8);
DrawText(s,w/10,h-getStringHeight(s)*2);
repaint;
//переменые
h2:=h/2;
w2:=w/2;
plh:=23;
plw:=10;
tsize:=24;
jspeed:=5;
anims:=5;
stopcr[1]:=1; //кадров анимации
stopcr[0]:=0; //и начальный кадр
runcr[1]:=6; //бег
runcr[0]:=stopcr[1];
dragcr[1]:=1; //торможение
dragcr[0]:=runcr[0]+runcr[1];
upcr[1]:=1; //прыжок
upcr[0]:=dragcr[0]+dragcr[1];
aircr[1]:=1;  //полет
aircr[0]:=upcr[0]+upcr[1];
downcr[1]:=1; //падение
downcr[0]:=aircr[0]+aircr[1];
vcr2:=(downcr[0]+downcr[1]);
//сортируем
stopcr[1]:=stopcr[0]+stopcr[1]-1;
runcr[1]:=runcr[0]+runcr[1]-1;
dragcr[1]:=dragcr[0]+dragcr[1]-1;
upcr[1]:=upcr[0]+upcr[1]-1;
aircr[1]:=aircr[0]+aircr[1]-1;
downcr[1]:=downcr[0]+downcr[1]-1;
//переменные
ht:=h/tsize+1;
wt:=w/tsize+1;
setFont(0,1,16);
ha2:=getStringHeight('SAMPLE TEXT'); //высота лого
setFont(0,0,8);
ha:=getStringHeight('SAMPLE TEXT');
hd:=w/4/ha*ha; //высота окна текста
bh:=w*h/5000; //размер полкнопки
url:='mssite.houa.org';
sort:='name';
nn:='\';
delayfps:=15;
deffps:=40;
layer[0]:=0; //начало каждого слоя картинок
layer[1]:=layer[0]+10;
layer[2]:=layer[1]+20;
layer[3]:=layer[2]+20; //анимации

//загрузка графики
//задний слой
for i:=layer[0]+1 to layer[0]+2 do
tile[i]:=loadImage('/img/tiles/1/tile'+(i)+'.png');

for i:=layer[0]+3 to layer[0]+4 do
tile[i]:=rotate_image_from_image(tile[layer[0]+2],0,0,24,24,i-layer[0]);
tile[i]:=rotate_image_from_image(tile[layer[0]+2],0,0,24,24,6);

//основной
for i:=layer[1]+1 to layer[1]+8 do
tile[i]:=loadImage('/img/tiles/2/tile'+(i-layer[1])+'.png');

//анимации и объекты
i2:=layer[3]+layer[1];
for i:=1 to 2 do
tile[i2+i]:=rotate_image_from_image(tile[layer[1]+5],i*tsize,0,tsize,tsize,0);
tile[layer[1]+5]:=rotate_image_from_image(tile[layer[1]+5],0,0,24,24,0);
i2:=i2+i-1;
for i:=1 to 1 do
tile[i2+i]:=rotate_image_from_image(tile[layer[1]+6],i*tsize,0,tsize,tsize,0);
tile[layer[1]+6]:=rotate_image_from_image(tile[layer[1]+6],0,0,24,24,0);
i2:=i2+i-1;
for i:=1 to 2 do //панели
tile[i2+i]:=rotate_image_from_image(tile[layer[1]+8],i*tsize,0,tsize,tsize,0);
i2:=i2+i-2; //-3
for i:=3 to 4 do
tile[i2+i]:=rotate_image_from_image(tile[layer[1]+8],i*tsize,0,tsize,tsize,0);
i2:=i2+i-2; //-3
for i:=3 to 4 do
tile[i2+i]:=rotate_image_from_image(tile[layer[1]+8],i*tsize,0,tsize,tsize,2);
//остальные 2 вариации

for i3:=4 to 5 do begin
i2:=i2+i-0; //-3
for i:=1 to 2 do
tile[i2+i]:=rotate_image_from_image(tile[layer[1]+8],i*tsize,0,tsize,tsize,i3);
i2:=i2+i-2; //-3
for i:=3 to 4 do
tile[i2+i]:=rotate_image_from_image(tile[layer[1]+8],i*tsize,0,tsize,tsize,i3);
i2:=i2+i-2; //-3
for i:=3 to 4 do
tile[i2+i]:=rotate_image_from_image(tile[layer[1]+8],i*tsize,0,tsize,tsize,2+i3);
end;

tile[layer[1]+8]:=rotate_image_from_image(tile[layer[1]+8],0,0,24,24,0);
tile[layer[1]+9]:=rotate_image_from_image(tile[layer[1]+8],0,0,24,24,4);
tile[layer[1]+10]:=rotate_image_from_image(tile[layer[1]+8],0,0,24,24,5);


//редактор
for i:=layer[2]+1 to layer[2]+5 do
begin
tile[i]:=loadImage('/editor/tiles/tile'+(i-layer[2])+'.png');
end;

//анимация Челл
for i:=0 to vcr2-1 do begin
chell[i]:=loadImage('/img/chell'+i+'.png');
if i>=stopcr[1] then sipl[i]:=getImageWidth(chell[i])/2-anims
else sipl[i]:=0;
end;
for i:=vcr2 to vcr2*2-1 do begin
chell[i]:=rotate_image_from_image(chell[i-vcr2],0,0,
getImageWidth(chell[i-vcr2]),getImageHeight(chell[i-vcr2]),2);
end;

if h>200 then menubg:=loadImage('/img/menu.png');

//RMS
rms:=OpenRecordStore('Data');
if (ReadRecordStoreEntry(rms,1)<>'051') then begin
//первый запуск программы
i2:=0;
repeat
test:=openResource('/maps/test'+i2+'.lvl');
if not (resourceAvailable(test)) then break;
i2:=i2+1;
closeResource(test);
until false;
maps:=i2-1; //всего карт
clvl:=0; //пройдено
keystype:=1; //тип управления
music:=1; //музыка
graphic:=0; //качество графики
awind:=125; //прозрачность окон
lsoft:=-6; //левый софт
rsoft:=-7; //ну даже не знаю...
k_up:=KeyToAction(KE_KEY2);
k_down:=KeyToAction(KE_KEY8);
k_left:=KeyToAction(KE_KEY4);
k_right:=KeyToAction(KE_KEY6);
touch:=0; //тачскрин
//modset:=''; //выбранный мод
for i:=1 to 20 do i2:=addRecordStoreEntry(rms,''); //создание ячеек
ModifyRecordStoreEntry(rms,'051',1);
ModifyRecordStoreEntry(rms,''+maps,2);
ModifyRecordStoreEntry(rms,path,3);
//4 - clvl
//5 - music (запрос на включение ниже)
//6 - graphic
ModifyRecordStoreEntry(rms,''+keystype,7);
ModifyRecordStoreEntry(rms,''+awind,8);
ModifyRecordStoreEntry(rms,''+lsoft,9);
ModifyRecordStoreEntry(rms,''+rsoft,10);
ModifyRecordStoreEntry(rms,''+k_up,11);
ModifyRecordStoreEntry(rms,''+k_down,12);
ModifyRecordStoreEntry(rms,''+k_left,13);
ModifyRecordStoreEntry(rms,''+k_right,14);
//15 - touch
//16 - modset (none)
stemp:='Включить музыку?';
Format;
tmenu[2]:='Да';tmenu[3]:='Нет';
SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
for i:=0 to max do DrawText(getitem(2,i),
w2-getStringWidth(getitem(2,i))/2,h2+ha*i-ha*max/2);
DrawText(tmenu[2],w/20,h-ha-5);
DrawText(tmenu[3],w-getStringWidth(tmenu[3])-w/20,h-ha-5);
repaint;
repeat

if touch=0 then touch:=pointer_state;
if touch=1 then begin
ts:=true;
if (pointer_released_x>w2) then music:=0;
break;
end;

key2:=getKeyClicked;
if (key2=lsoft) or (keyToAction(key2)=GA_FIRE) then break;
if key2=rsoft then begin
music:=0;
break;
end;
Delay(25);
until false;
ModifyRecordStoreEntry(rms,''+music,5);
ModifyRecordStoreEntry(rms,''+touch,15);
end;
else begin
maps:=stringToInteger(ReadRecordStoreEntry(rms,2));
path:=ReadRecordStoreEntry(rms,3);
clvl:=stringToInteger(ReadRecordStoreEntry(rms,4));
music:=stringToInteger(ReadRecordStoreEntry(rms,5));
graphic:=stringToInteger(ReadRecordStoreEntry(rms,6));
keystype:=stringToInteger(ReadRecordStoreEntry(rms,7));
awind:=stringToInteger(ReadRecordStoreEntry(rms,8));
lsoft:=stringToInteger(ReadRecordStoreEntry(rms,9));
rsoft:=stringToInteger(ReadRecordStoreEntry(rms,10));
k_up:=stringToInteger(ReadRecordStoreEntry(rms,11));
k_down:=stringToInteger(ReadRecordStoreEntry(rms,12));
k_left:=stringToInteger(ReadRecordStoreEntry(rms,13));
k_right:=stringToInteger(ReadRecordStoreEntry(rms,14));
touch:=stringToInteger(ReadRecordStoreEntry(rms,15));
//modset:=ReadRecordStoreEntry(rms,16);
if touch=1 then ts:=true;
end;
closeRecordStore(rms);
{
izometry:=true;
if izometry then begin
//тест преобразования в изометрию
for i:=1 to 6 do begin
CreateImage(tsize+tsize/2,tsize+tsize/2);
Replace; //рисуем в пикче
DrawImage(tile[layer[1]+i],tsize/2,tsize/2);
//2,4,3,1 - стороны пикчи
draw_transformed(tile[i+layer[1]],tsize,0,tsize+tsize/2,tsize/2,tsize/2,tsize/2,0,0);
draw_transformed(tile[i+layer[1]],tsize/2,tsize/2,tsize/2,tsize+tsize/2,0,tsize,0,0);
Replace; //конец создания
tile[i+layer[1]]:=ReplaceColor(GetImage,-1,0);
i3:=TranslateColor(255,0,0,0);
i4:=gfx.GetColor(GetImage,tsize/2,tsize/2);
tile[i+layer[1]]:=ReplaceColor(tile[i+layer[1]],i3,i4);
end;
end;
}


CreateImage(tsize,tsize);
tile[0]:=GetImage;
//alphabg:=SetOpaque(GetImage,awind);
CreateImage(w,hd);
for i:=0 to 4 do dialogbg[i]:=SetOpaque(GetImage,awind/5*(i+1));

CreateImage(bh*2,bh*2);
sbutt:=SetOpaque(GetImage,85);

{
CreateImage(ha*2,ha*2);
//Replace;
SetColor(0,0,255);
FillRect(0,0,ha*2-1,ha*2-1);
SetColor(255,255,255);
FillTriangle(0,ha*2-1,ha*2-1,0,ha*2-1,ha*2-1);
//Replace;
sbutt[1]:=SetOpaque(GetImage,85);
PutImage(sbutt[1]);
//Replace;
SetColor(0,0,0);
DrawTriangle(0,ha*2-1,ha*2-1,0,ha*2-1,ha*2-1);
//Replace;
sbutt[1]:=ReplaceColor(GetImage,2097152255,0);
for i:=2 to 4 do sbutt[i]:=rotate_image_from_image(sbutt[1],0,0,ha*2,ha*2,i+3);
}
ArraysReset;

//музыка
if (music=1) then begin
if not openPlayer('/main.mid','audio/midi') then delay(1);
if not setPlayerCount(1) then delay(1);
if not startPlayer then delay(1);
end;
else if music=0 then stopPlayer;
end;


procedure ModLoader;
begin
if modset<>'' then begin //моддинг
test:=openResource('mods/'+modset+'/modset');
if not (resourceAvailable(test)) then begin
SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
DrawText('mods/'+modset+'/modset не найден',w/10,h-ha-5);
modset:='';
repaint;
Delay(1000);
GameLoader;
end;
SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
DrawText('Загрузка мода...',w/10,h-ha-5);
repaint;
animpack:=stringToInteger(readLine(test));
texturepack:=stringToInteger(readLine(test));
levelpack:=stringToInteger(readLine(test));
tsize:=stringToInteger(readLine(test)); //размер тайлов
plw:=stringToInteger(readLine(test)); //ширина игрока
plh:=stringToInteger(readLine(test)); //высота игрока
jspeed:=stringToInteger(readLine(test)); //сила прыжка
closeResource(test);

//загрузка анимпака
if animpack=1 then begin
test:=openResource('mods/'+modset+'/animations/animset');
if not (resourceAvailable(test)) then begin
SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
DrawText('mods/'+modset+'/animations/animset не найден',w/10,h-ha-5);
modset:='';
repaint;
Delay(1000);
GameLoader;
end;
stopcr[1]:=stringToInteger(readLine(test));
runcr[1]:=stringToInteger(readLine(test));
dragcr[1]:=stringToInteger(readLine(test));
upcr[1]:=stringToInteger(readLine(test));
aircr[1]:=stringToInteger(readLine(test));
downcr[1]:=stringToInteger(readLine(test));
anims:=stringToInteger(readLine(test)); //общая корректировка x-выравнивания
closeResource(test);

stopcr[0]:=0;
runcr[0]:=stopcr[1];
dragcr[0]:=runcr[0]+runcr[1];
upcr[0]:=dragcr[0]+dragcr[1];
aircr[0]:=upcr[0]+upcr[1];
downcr[0]:=aircr[0]+aircr[1];
vcr2:=(downcr[0]+downcr[1]);
//сортируем
stopcr[1]:=stopcr[0]+stopcr[1]-1;
runcr[1]:=runcr[0]+runcr[1]-1;
dragcr[1]:=dragcr[0]+dragcr[1]-1;
upcr[1]:=upcr[0]+upcr[1]-1;
aircr[1]:=aircr[0]+aircr[1]-1;
downcr[1]:=downcr[0]+downcr[1]-1;

for i:=0 to vcr2-1 do begin
chell[i]:=loadImage('mods/'+modset+'/animations/'+i+'.png');


SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
drawimage(chell[i],0,0);
DrawText(''+i,w2,h2);
repaint;
if i>=stopcr[1] then sipl[i]:=getImageWidth(chell[i])/2-anims
else sipl[i]:=0;
end;
for i:=vcr2 to vcr2*2-1 do begin
chell[i]:=rotate_image_from_image(chell[i-vcr2],0,0,
getImageWidth(chell[i-vcr2]),getImageHeight(chell[i-vcr2]),2);


SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
drawimage(chell[i],0,0);
DrawText(''+i,w2,h2);
repaint;
end;
end;
end;

end;


Procedure fps;
begin
n2:=n2+1;
if ((lastSavedTime-getRelativeTimeMs)<-1000)
or (getRelativeTimeMs<lastSavedTime) then
begin
kolvofps:=n2;
lastSavedTime:=getRelativeTimeMs;
n2:=0;
end;
SetColor(0,0,0);
drawtext(''+kolvofps,1,h-ha);

n:=getRelativeTimeMs-savtime;
if n<deffps then delayfps:=delayfps+1;
if n>deffps then delayfps:=delayfps-1;
if delayfps<0 then delayfps:=0;
if delayfps>40 then delayfps:=40;
savtime:=getRelativeTimeMs;
if dbg=1 then begin
SetColor(0,0,0);
if delayfps<>0 then drawtext(''+delayfps,1,h-ha*2);
drawtext(''+t2,ha*2,h-ha);
drawtext(''+t1,ha*2,h-ha*2);
end;
end;


procedure OldBits(bx,by,vb: integer);
begin
{i3:=random(10);
if vb=1 then begin
for i2:=0 to i3 do
Plot(bx+random(tsize)+(5-random(11)),by-random(tsize/2)-random(3));
end;
if vb=2 then begin
for i2:=0 to i3 do
Plot((bx+random(tsize/2)+random(3)),by+random(tsize)+5-random(11));
end;
if vb=3 then begin
for i2:=0 to i3 do
Plot(bx+random(tsize)+(5-random(11)),by+random(tsize/2)+random(3));
end;
if vb=4 then begin
for i2:=0 to i3 do
Plot((bx-random(tsize/2)-random(3)),by+random(tsize)+5-random(11));
end;}
end;


procedure BitsBoom;
begin
if (bt[i2-1]) then begin
//ложное открытие частиц
if i2=1 then i3:=4 else i3:=6;
for i:=0 to 10 do begin
bt[i2-1]:=false;
bit[i3,i]:=bit[i3,i]+random(7)-3;
bit[i3+1,i]:=bit[i3+1,i]+random(7)-3;
if random(25)=1 then bit[i3,i]:=-100;
if random(25)=1 then bit[i3+1,i]:=-100;
if (bit[i3,i]>0) and (bit[i3+1,i]>0) then begin
Plot(bit[i3,i]-dmx[1],bit[i3+1,i]-dmy[1]);
bt[i2-1]:=true;
end;
end;
end;

end;


procedure Bits(bx,by,vb: integer);
begin
if i2=2 then i3:=2 else i3:=0;

if (bt[2]) then begin
//закрытие частиц
if vb=0 then begin
bt[3]:=false;
for i:=0 to 10 do begin
bit[i3,i]:=bit[i3,i]+random(3)-1;
bit[i3+1,i]:=bit[i3+1,i]+random(3)-1;
if random(6)=1 then bit[i3,i]:=-100;
if random(6)=1 then bit[i3+1,i]:=-100;
if (bit[i3,i]>0) and (bit[i3+1,i]>0) then begin
Plot(bit[i3,i]-dmx[1],bit[i3+1,i]-dmy[1]);
bt[3]:=true;
end;
end;
end;
else begin
//анимация частиц

if vb=1 then begin
for i:=0 to 10 do begin
bit[i3,i]:=bit[i3,i]+random(3)-1;
bit[i3+1,i]:=bit[i3+1,i]-random(3);
if bit[i3,i]<bx-5 then bit[i3,i]:=bx-5;
if bit[i3,i]>bx+tsize+5 then bit[i3,i]:=bx+tsize+5;
if bit[i3+1,i]<by-tsize/2 then begin
bit[i3+1,i]:=by;
bit[i3,i]:=bx+random(tsize+1);
end;
Plot(bit[i3,i]-dmx[1],bit[i3+1,i]-dmy[1]);
end;
end;

if vb=2 then begin
for i:=0 to 10 do begin
bit[i3,i]:=bit[i3,i]+random(3);
bit[i3+1,i]:=bit[i3+1,i]+random(3)-1;
if bit[i3+1,i]<by-5 then bit[i3+1,i]:=by-5;
if bit[i3+1,i]>by+tsize+5 then bit[i3+1,i]:=by+tsize+5;
if bit[i3,i]>bx+tsize/2 then begin
bit[i3,i]:=bx;
bit[i3+1,i]:=by+random(tsize+1);
end;
Plot(bit[i3,i]-dmx[1],bit[i3+1,i]-dmy[1]);
end;
end;

if vb=3 then begin
for i:=0 to 10 do begin
bit[i3,i]:=bit[i3,i]+random(3)-1;
bit[i3+1,i]:=bit[i3+1,i]+random(3);
if bit[i3,i]<bx-5 then bit[i3,i]:=bx-5;
if bit[i3,i]>bx+tsize+5 then bit[i3,i]:=bx+tsize+5;
if bit[i3+1,i]>by+tsize/2 then begin
bit[i3+1,i]:=by;
bit[i3,i]:=bx+random(tsize+1);
end;
Plot(bit[i3,i]-dmx[1],bit[i3+1,i]-dmy[1]);
end;
end;

if vb=4 then begin
for i:=0 to 10 do begin
bit[i3,i]:=bit[i3,i]-random(3);
bit[i3+1,i]:=bit[i3+1,i]+random(3)-1;
if bit[i3+1,i]<by-5 then bit[i3+1,i]:=by-5;
if bit[i3+1,i]>by+tsize+5 then bit[i3+1,i]:=by+tsize+5;
if bit[i3,i]<bx-tsize/2 then begin
bit[i3,i]:=bx;
bit[i3+1,i]:=by+random(tsize+1);
end;
Plot(bit[i3,i]-dmx[1],bit[i3+1,i]-dmy[1]);
end;
end;

end;

end;
else begin //создание частиц
bt[2]:=true;
if (vb=1) or (vb=3) then begin
for i:=0 to 10 do begin
bit[i3,i]:=bx+random(tsize+1);
bit[i3+1,i]:=by;
end;
end;
if (vb=2) or (vb=4) then begin
for i:=0 to 10 do begin
bit[i3,i]:=bx;
bit[i3+1,i]:=by+random(tsize+1);
end;
end;

end;
end;


procedure Pause;
begin
DrawImage(dialogbg[4],0,h2-hd/2);
SetColor(0,0,0);
s:='Нажмите любую клавишу';
DrawText(s,w2-getStringWidth(s)/2,h2-ha/2);
repaint;
repeat
key:=GetKeyClicked;
delay(100);
until key<>0;
paused:=false;
end;


procedure MSLogo;
begin
repeat
SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
for i:=1 to h/100 do DrawLine(0,h2-i,w,h2-i);
repaint;
until false;
end;


function TouchText(tx,ty,i6: integer): boolean;
begin
ox:=pointer_pressed_x;
oy:=pointer_pressed_y;
if i6=0 then s:=tmenu[im];
if i6=1 then s:=getitem(0,im);
if i6=2 then s:=getitem(2,im);
if pointer_state=1 then
if (oy>ty) and (oy<ty+ha) then begin
if (ox>tx) and (ox<tx+getStringWidth(s)) then TouchText:=true;
if (ox<tx) then key2:=GA_LEFT;
if (ox>tx+getStringWidth(s)) then key2:=GA_RIGHT;
end;
end;


function TButton(tx,ty: integer): boolean;
begin
ox:=pointer_pressed_x;
oy:=pointer_pressed_y;
if pointer_state=1 then
if (ox>tx) and (ox<tx+bh*2) then
if (oy>ty) and (oy<ty+bh*2) then begin
TButton:=true;
ox:=0;
oy:=0;
end;
end;


procedure BasicMenu(im2: integer);
begin //шаблон меню
SetColor(255,255,255);
FillRect(0,0,w,h);
drawImage(menubg,w-getImageWidth(menubg),h-getImageHeight(menubg));
key2:=keyToAction(GetKeyClicked);
if key2=GA_UP then if pos<2 then pos:=im2 else pos:=pos-1;
if key2=GA_DOWN then if pos>im2-1 then pos:=1 else pos:=pos+1;
//рисуем каждый элемент меню
for im:=1 to im2 do begin
if (touch=0) and (TouchText(5,im*ha+h/4,0)) then begin
key2:=GA_FIRE;
pos:=im;
end;
if im=pos then begin
// Если пункт меню выбран
SetColor(0,0,0);
FillRect(0,im*ha+h/4,getStringWidth(tmenu[im])+10,ha);
SetColor(255,255,255);
DrawText(tmenu[im],5,im*ha+h/4);
end
else begin
//если он не выбран
SetColor(0,0,0);
DrawText(tmenu[im],5,im*ha+h/4);
end
end;
touch:=pointer_state;
setFont(0,1,16);
SetColor(0,0,0);
DrawText(tmenu[0],w2-getStringWidth(tmenu[0])/2,h/20);
setFont(0,0,8);
if menubits then begin
tmp[2]:=tsize;
tsize:=25;
Bits(tmp[0]+50,tmp[1]+26,1);
tsize:=tmp[2];
end;
repaint;
delay(25);
end;


procedure BasicMenu2(im2: integer);
begin //со скролингом
SetColor(255,255,255);
FillRect(0,0,w,h);
drawImage(menubg,tmp[0],tmp[1]);
if pos*ha+dmy[0]<h/20+ha2 then dmy[0]:=dmy[0]+ha/2;
if pos*ha+dmy[0]>h-ha then dmy[0]:=dmy[0]-ha/2;
key2:=GetKeyClicked;
if keyToAction(key2)=GA_UP then
if pos<1 then pos:=im2 else pos:=pos-1;
if keyToAction(key2)=GA_DOWN then
if pos>im2-1 then pos:=0 else pos:=pos+1;
//рисуем каждый элемент меню
for im:=0 to getsize(0)-1 do begin
if (touch=0) and (TouchText(5,im*ha+dmy[0],1)) then begin
key2:=KE_KEY5;
pos:=im;
end;
if im<>pos then begin
//если он не выбран
SetColor(0,0,0);
DrawText(getitem(0,im),5,im*ha+dmy[0]);
end;
else begin
//если пункт меню выбран
SetColor(0,0,0);
FillRect(0,im*ha+dmy[0],
getStringWidth(getitem(0,im))+10,ha);
SetColor(255,255,255);
DrawText(getitem(0,im),5,im*ha+dmy[0]);
end;
end;
touch:=pointer_state;
SetColor(255,255,255);
FillRect(0,0,w,h/20+ha2);
setFont(0,1,16);
SetColor(0,0,0);
DrawText(tmenu[0],w2-getStringWidth(tmenu[0])/2,h/20);
setFont(0,0,8);
tmp[2]:=tsize;
tsize:=25;
Bits(tmp[0]+50,tmp[1]+26,1);
tsize:=tmp[2];
repaint;
delay(20);
end;


///////////////////////
/////Редактор карт/////
///////////////////////
procedure MapOptimize;
begin //удаляет то что не видно
spawnx:=0;
spawny:=0;
scy2:=0;
scx2:=0;
i4:=layer[1]-1;
for i:=0 to mapy do begin
for i2:=0 to mapx do begin
SetArr(1);
if (GetInt(i2,i)>0) and (GetInt(i2,i)<3) then begin
SetArr(0);
PutInt(i2,i,i4);
end;
end;
end;

end;
procedure Manager;
begin
if path='' then  path:='/';
if path='/' then begin
parse2(get_roots,'|');
byte:=getsize(0);
end;
else begin
if come<>2 then path:=copy(path,0,length(path)-length(name));
parse2(get_dirs(path),'|');
byte:=getsize(0)-1; // в этой папке
if getsize(0)>0 then byte:=byte+1; //фикс
parse2('...|'+get_dirs(path)+'В этой папке|'+get_files(path),'|');
end;
dmy[0]:=h2-(getsize(0)+1)*ha/2;
if dmy[0]<h/20+ha2 then dmy[0]:=h/20+ha2;
pos:=0;
come:=2;
repeat
BasicMenu2(getsize(0)-2);
if key2=rsoft then begin
name:='';
Game;
end;
if (keyToAction(key2)=GA_FIRE) and (pos<>byte) then begin
//переход вверх
if (pos=0) and (path<>'/') then begin
i2:=length(path)-2;
for i:=i2 downto 0 do begin
if getChar(path,i)='/' then begin
path:=copy(path,0,i+1);
break;
end;
end;
end;
//вниз в выбранную папку
else begin
if (pos<byte) then begin
if (pos>0) or (path='/') then path:=path+getitem(0,pos);
end;
end;
//открываем файл
if (pos>byte) then begin
name:=getitem(0,pos);
path:=path+name;
if file_exists(path)=1 then begin
come:=3;
ledit:=1;
Game;
end;
end;

Manager;
end;
until (keyToAction(key2)=GA_FIRE) and (pos=byte);
showTextBox('Имя карты','',99,TF_ANY);
con:=createCommand('OK',CM_OK,0);
cback:=createCommand('Назад',CM_BACK, 2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
name:=getTextBoxString+'.lvl';
path:=path+name;
end;
showCanvas;
if clicked=cback then Manager;
Game;
end;


procedure SaveMap;
begin
i3:=file_exists(path);
if i3=1 then delete_file(path);
file_create(path);
i:=open_file(path);
jsr75i.write_byte(mapx);
jsr75i.write_byte(mapy);
jsr75i.write_byte(51);

SetArr(0);
for i:=0 to mapy do
for i2:=0 to mapx do
jsr75i.write_byte(GetInt(i2,i));

//пакуем объекты 2 слоя
SetArr(1);
for i:=0 to mapy do
for i2:=0 to mapx do
begin
i3:=GetInt(i2,i);
jsr75i.write_byte(i3);
if (i3>4) then begin
if (i3<11) then begin
if (i3<>7) then begin
if i3>8 then i3:=8;
//выбираем массив типа объектов
SetArr(i3);
//узнаем номер объекта в массиве
for byte:=0 to 4 do if GetInt(byte,0)=i*mapx+i2 then break;
//пишем данные
if byte<5 then begin
if i3=5 then i3:=1
else if i3=8 then i3:=2
else i3:=3;
jsr75i.write_byte(i3); //колво байтов в объекте
for i4:=1 to i3 do jsr75i.write_byte(GetInt(byte,i4));
end;
else for i4:=1 to i3 do jsr75i.write_byte(0);
SetArr(1);

end;
end;
end;

end;

SetArr(2);
for i:=0 to mapy do
for i2:=0 to mapx do
begin
i3:=GetInt(i2,i);
if i3>0 then begin
jsr75i.write_byte(i2);
jsr75i.write_byte(i);
jsr75i.write_byte(i3);
end;

end;
//разделитель 3 слоя и текста
jsr75i.write_byte(255);

for i:=1 to texts do begin
jsr75i.write_string_a(tgame[i-1]);
jsr75i.write_byte(10);
//чтобы не было виса при пустом авторе
jsr75i.write_string_a(tauthor[i-1]+' ');
jsr75i.write_byte(10);
end;

jsr75i.flush;
i:=close_file(path);
DrawText('Сохранено.',w/10,h-ha-5);
repaint;
Delay(1000);
end;


procedure ReloadMap;
begin //востановление объектов
SetArr(1);
for i:=0 to mapy do
for i2:=0 to mapx do begin
i4:=GetInt(i2,i);
if i4<0 then PutInt(i2,i,-i4);
if i4>layer[3] then begin
if i4<layer[3]+3 then PutInt(i2,i,5); //дверь
if i4=layer[3]+3 then PutInt(i2,i,6); //кнопка
for i3:=0 to 2 do
if (i4>layer[3]+3+i3*9) and (i4<layer[3]+12+i3*9) then PutInt(i2,i,8+i3); //панель
end;
end;
SetArr(2);
for i:=0 to mapy do
for i2:=0 to mapx do begin
if GetInt(i2,i)<0 then PutInt(i2,i,-GetInt(i2,i));
end;
end;


procedure TestMap;
begin
dmx[1]:=0;
dmy[1]:=0;
x:=0;y:=0;
allmapx:=(mapx+1)*tsize-w;
allmapy:=(mapy+1)*tsize-h;
SetArr(2);
for i:=0 to mapy do
begin
for i2:=0 to mapx do
begin
if GetInt(i2,i)=1 then
begin //игрок
x:=i2*tsize+tsize/2-plw/2;
y:=i*tsize+tsize-plh;
if spawnx<>0 then x:=spawnx;
if spawny<>0 then y:=spawny;
if dmx[1]<>x-w2+7 then
begin
dmx[1]:=trunc(x)-w2+7;
if dmx[1]>allmapx then dmx[1]:=allmapx;
if dmx[1]<0 then dmx[1]:=0;
end;
if dmy[1]<>y-h2 then
begin
dmy[1]:=trunc(y)-h2;
if dmy[1]>allmapy then dmy[1]:=allmapy;
if dmy[1]<0 then dmy[1]:=0;
end;
end;

end;
end;

for i:=1 to 5 do tmp[i]:=0;
for i:=0 to 7 do begin
for i2:=0 to 10 do bit[i,i2]:=-100;
end;
vr[1]:=0;vr[2]:=0;
iner:=0;usk:=0;
pox:=0;poy:=0;
bt[2]:=false;
aimmode:=false;
viewmode:=false;
viewtext:=0;
if keystype=2 then r:=1 else r:=0;
key:=0;
touch:=0;
end;


procedure DownloadMap;
begin
spawnx:=0;
spawny:=0;
mapx:=connect.getb(0);
mapy:=connect.getb(1);
layers:=connect.getb(2);
if (layers<>51) and (layers<>5) then begin
DrawText('Карта не поддерживается',w/10,h-ha-5);
repaint;
connect.close;
Delay(1000);
come:=4;
Game;
end;
else begin
ArraysReset;
i4:=3;



SetArr(0);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do begin
PutInt(i2,i,connect.getb(i4));
i4:=i4+1;
end;

SetArr(1);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do
begin
i3:=connect.getb(i4);
i4:=i4+1;
PutInt(i2,i,i3);

if (i3>4) then
if (i3<11) then
if i3<>7 then begin
if i3>8 then i3:=8;
SetArr(i3);
for i5:=0 to 14 do
if GetInt(i5,0)=0 then begin
PutInt(i5,0,i*mapx+i2);
byte:=connect.getb(i4); //сколько байтов в объекте
i4:=i4+1;
for i6:=1 to byte do begin
PutInt(i5,i6,connect.getb(i4));
i4:=i4+1;
end;

SetArr(1);
break;
end;
end;

end;

texts:=0;

SetArr(2);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do
for i2:=0 to mapx+1 do
PutInt(i2,i,0);
repeat
i3:=connect.getb(i4);
i4:=i4+1;
if i3<>-1 then begin
i:=connect.getb(i4);
i4:=i4+1;
byte:=connect.getb(i4);
i4:=i4+1;
PutInt(i3,i,byte);
if byte=5 then begin //текст
ntext[texts]:=i*mapx+i3;
texts:=texts+1;
end;
end;
else break;
until false;


if texts>0 then begin
byte:=i4-1;
for i:=1 to texts do begin
tgame[i-1]:='';
repeat
byte:=byte+1;
if connect.getb(byte)<>10 then
tgame[i-1]:=tgame[i-1]+chr(connect.getb(byte));
else break;
until false;
tgame[i-1]:=win2utf(tgame[i-1]);
tauthor[i-1]:='';
repeat
byte:=byte+1;
if connect.getb(byte)<>10 then
tauthor[i-1]:=tauthor[i-1]+chr(connect.getb(byte))
else break;
until false;
tauthor[i-1]:=win2utf(tauthor[i-1]);
tauthor[i-1]:=copy(tauthor[i-1],0,length(tauthor[i-1])-1);
end;
end;

connect.close;
end;

TestMap;
MapOptimize;
end;


procedure SetTile;
begin
SetArr(er);
if (er=0) or (er=2) then begin //просто быстрая установка тайла
showTextBox('Тайл ',''+GetInt(ex,ey),3,TF_NUMERIC);
con:=createCommand('ОК',CM_OK, 1);
cback:=createCommand('Назад',CM_BACK, 2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
click:=stringToInteger(getTextBoxString);
if click<100 then PutInt(ex,ey,click);
end;
//key2:=0;
showCanvas;
end;

if er=1 then begin //настройка объектов
i3:=GetInt(ex,ey);
if (i3>4) and (i3<11) then
if i3<>7 then begin //объекты
if i3>8 then i3:=8;
SetArr(i3);

if i3=5 then i4:=1
else if i3=8 then i4:=2
else i4:=3;

for byte:=0 to 14 do if GetInt(byte,0)=ey*mapx+ex then break;

if byte<15 then //номер объекта
for i:=1 to i4 do begin
s:='Объект';
if (i3=8) then begin
if (GetInt(byte,i)>100) then PutInt(byte,i,-(GetInt(byte,i)-100));
if i=1 then s:='Y-скорость';
if i=2 then s:='X-скорость';
end;
showTextBox(s+' ['+byte+','+i+']',''+GetInt(byte,i),3,TF_NUMERIC);
con:=createCommand('ОК',CM_OK, 1);
cback:=createCommand('Назад',CM_BACK,2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
click:=stringToInteger(getTextBoxString);
if click>99 then click:=99;
if click<-99 then click:=-99;
if click<0 then begin
if (i3=8) then click:=-click+100
else click:=0;
end;
PutInt(byte,i,click);
end;
if clicked=cback then break;
end;
else begin
showCanvas;
SetColor(0,0,0);
DrawText('Объект не найден.',ha,h-ha*2);
repaint;
Delay(1000);
end;
showCanvas;

end;
end;

if er=2 then begin
end;

end;


procedure SetAdds;
begin //доп к тайлам
if efill=false then begin
i3:=ex;
i4:=ey;
end;
SetArr(er);

if er=1 then begin
//удаление объектов если они есть
i:=GetInt(i3,i4);
if (elar[er]<>i) then begin
if (i=3) or (i=5) or ((i>7) and (i<11)) then begin //разные объекты
SetArr(2);
PutInt(i3,i4,0);
SetArr(1);
end;
if (i>4) and (i<11) then begin
if (i<>7) then begin
if i>8 then i:=8;
SetArr(i);
if i=5 then i2:=1
else if i=8 then i2:=2
else i2:=3;
for byte:=0 to 14 do if GetInt(byte,0)=i4*mapx+i3 then break;
if byte<15 then for i:=0 to i2 do PutInt(byte,i,0);
end;

end;
end;
SetArr(0); //востановление фона
if GetInt(i3,i4)=layer[1]-1 then PutInt(i3,i4,0);
SetArr(1);

if (elar[er]=3) then begin //смерть для воды
SetArr(2);
PutInt(i3,i4,3);
SetArr(1);
end;

if (elar[er]=5) then begin //дверь
if elar[er]<>GetInt(i3,i4) then begin
SetArr(5);
for i:=0 to 14 do if GetInt(i,0)=0 then break;
//пишем данные
if i<15 then begin
PutInt(i,0,i4*mapx+i3);
for i2:=1 to 1 do PutInt(i,i2,0);
SetArr(2);
PutInt(i3,i4,layer[3]);
end;
else eok:=false;
SetArr(1);
end;
end;

if (elar[er]=6) then begin //кнопка
//привязка
if (GetInt(i3,i4)=6) then begin
if efill=false then begin
elink:=true;
elm:=6;
elx:=i3;
ely:=i4;
end;
end;
else begin //добавление
SetArr(6);
for i:=0 to 14 do if GetInt(i,0)=0 then break;
//пишем данные
if i<15 then begin
PutInt(i,0,i4*mapx+i3);
for i2:=1 to 3 do PutInt(i,i2,0);
end;
else eok:=false;
end;
SetArr(1);
end;

if (elar[er]=7) then begin //поле
SetArr(2);
PutInt(i3,i4,layer[3]+1);
SetArr(1);
end;

if (elar[er]>7) and (elar[er]<11) then begin //панель веры
if elar[er]<>GetInt(i3,i4) then begin
SetArr(8);
for i:=0 to 14 do if GetInt(i,0)=0 then break;
//пишем данные
if i<15 then begin
PutInt(i,0,i4*mapx+i3);
for i2:=1 to 2 do PutInt(i,i2,0);
SetArr(2);
PutInt(i3,i4,layer[3]+2+(elar[er] mod 8));
end;
else eok:=false;
SetArr(1);
end;
else SetTile;
end;

end;


if er=2 then begin

if (elar[er]<>GetInt(i3,i4)) then begin
if (GetInt(i3,i4)=5) then begin //текст
if texts>0 then texts:=texts-1;
//узнаем ид удаленного текста
for i2:=0 to texts do begin
if ntext[i2]=i4*mapx+i3 then break;
end;
tgame[i2]:='';
tauthor[i2]:='';
ntext[i2]:=0;
//смещаем данные вверх
for i:=i2+1 to texts+1 do begin
tgame[i-1]:=tgame[i];
tauthor[i-1]:=tauthor[i];
ntext[i-1]:=ntext[i];
end;
end;
end;

if (elar[er]=5) then begin //текст -_-
//изменение текста
if (GetInt(i3,i4)=5) and (texts>0) then begin
//узнаем ид текста
for i2:=0 to texts-1 do begin
if ntext[i2]=i4*mapx+i3 then break;
end;

if getChar(tgame[i2],length(tgame[i2])-1)=' ' then
tgame[i2]:=copy(tgame[i2],0,length(tgame[i2])-1);
showTextBox('Текст',''+tgame[i2],999,TF_ANY);
con:=createCommand('ОК',CM_OK, 1);
cback:=createCommand('Назад',CM_BACK, 2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
tgame[i2]:=getTextBoxString;
if getChar(tgame[i2],length(tgame[i2]))<>' ' then
tgame[i2]:=tgame[i2]+' ';

showTextBox('Автор',''+tauthor[i2],99,TF_ANY);
con:=createCommand('ОК',CM_OK, 1);
cback:=createCommand('Назад',CM_BACK, 2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
tauthor[i2]:=getTextBoxString;
end;

end;
showCanvas;
if clicked=cback then begin
come:=3;
ledit:=2;
Game;
end;

end;
//добавление текста
else begin
if (texts<20) then begin
showTextBox('Текст','',999,TF_ANY);
con:=createCommand('ОК',CM_OK, 1);
cback:=createCommand('Назад',CM_BACK, 2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
tgame[texts]:=getTextBoxString+' ';

showTextBox('Автор','',99,TF_ANY);
con:=createCommand('ОК',CM_OK, 1);
cback:=createCommand('Назад',CM_BACK, 2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
ntext[texts]:=i4*mapx+i3;
//сортировка
//узнаем приоритет текста
i2:=0;
for i:=0 to texts do begin
if (ntext[texts]>ntext[i]) then i2:=i2+1;
end;
tauthor[texts]:=getTextBoxString;
stemp:=tgame[texts];
texts:=texts+1;
i2:=i2+1;
//смещаем данные
for i:=texts downto i2 do begin
tgame[i]:=tgame[i-1];
tauthor[i]:=tauthor[i-1];
ntext[i]:=ntext[i-1];
end;
//востанавливаем наш текст
tgame[i2-1]:=stemp;
tauthor[i2-1]:=getTextBoxString;
ntext[i2-1]:=i4*mapx+i3;

end;
else tgame[texts]:='';

end;
showCanvas;
if clicked=cback then begin
come:=3;
ledit:=2;
Game;
end;

end;
else eok:=false; //больше 20 текстов
end;
end;

end;
end;


procedure SetDeletes;
begin
if efill=false then begin
i3:=ex;
i4:=ey;
end;

if er=1 then begin
SetArr(0); //востановление фона
if GetInt(i3,i4)=layer[1]-1 then PutInt(i3,i4,0);

SetArr(1);
if (GetInt(i3,i4)=3) then begin
SetArr(2);
PutInt(i3,i4,0);
SetArr(1);
end;

if (GetInt(i3,i4)=5) then begin
SetArr(2);
PutInt(i3,i4,0);
SetArr(5);
for i:=0 to 14 do if GetInt(i,0)=i4*mapx+i3 then break;
if i<15 then
for i2:=0 to 1 do PutInt(i,i2,0);
SetArr(1);
end;

if (GetInt(i3,i4)=6) then begin
SetArr(6);
for i:=0 to 14 do if GetInt(i,0)=i4*mapx+i3 then break;
if i<15 then
for i2:=0 to 3 do PutInt(i,i2,0);
SetArr(1);
end;

if (GetInt(i3,i4)=7) then begin
SetArr(2);
PutInt(i3,i4,0);
SetArr(1);
end;

if (GetInt(i3,i4)>7) and (GetInt(i3,i4)<11) then begin
SetArr(2);
PutInt(i3,i4,0);
SetArr(8);
for i:=0 to 14 do if GetInt(i,0)=i4*mapx+i3 then break;
if i<15 then
for i2:=0 to 2 do PutInt(i,i2,0);
SetArr(1);
end;

end;

if er=2 then begin
SetArr(2);
if (GetInt(i3,i4)=5) then begin //текст
if texts>0 then texts:=texts-1;
//узнаем ид удаленного текста
for i2:=0 to texts do begin
if ntext[i2]=i4*mapx+i3 then break;
end;
tgame[i2]:='';
tauthor[i2]:='';
ntext[i2]:=0;
//смещаем данные вверх
for i:=i2+1 to texts+1 do begin
tgame[i-1]:=tgame[i];
tauthor[i-1]:=tauthor[i];
ntext[i-1]:=ntext[i];
end;
end;
SetArr(2);
end;

end;


procedure LevelEditor;
begin
if ledit=0 then begin //новая карта
for i3:=0 to 2 do begin
SetArr(i3);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do
PutInt(i2,i,0);
end;
for i:=0 to texts do ntext[texts]:=0;
texts:=0;
ArraysReset;
ex:=0;
ey:=0;
end;

if ledit=1 then begin //открытие карты
i:=open_file(path);
mapx:=jsr75i.read_byte;
mapy:=jsr75i.read_byte;
layers:=jsr75i.read_byte; //версия карты
//х*у,действия к объекту
ArraysReset;
if (layers<2) or ((layers>3) and (layers<>5) and (layers<>51)) then begin
DrawText('Файл не является картой',w/10,h-ha-5);
repaint;
i:=close_file(path);
Delay(1000);
Manager;
end;

if (layers=2) or (layers=3) then begin
for i3:=0 to 1 do
begin
SetArr(i3);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do PutInt(i2,i,jsr75i.read_byte);
end;
texts:=0;
//объекты
SetArr(i3);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do
begin
byte:=jsr75i.read_byte;
PutInt(i2,i,byte);
if byte=5 then begin //текст
ntext[texts]:=i*mapx+i2;
texts:=texts+1;
end;
end;
//загрузка текстов
if texts>0 then begin
test:=jsr75i.get_stream;
for i:=1 to texts do begin
tgame[i-1]:=win2utf(readline(test));
if layers<>4 then begin
tauthor[i-1]:=win2utf(readline(test));
tauthor[i-1]:=copy(tauthor[i-1],0,length(tauthor[i-1])-1);
end;
end;
closeResource(test);
end;
i:=close_file(path);
end;

if (layers=5) or (layers=51) then begin
SetArr(0);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do
PutInt(i2,i,jsr75i.read_byte);

SetArr(1);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do
begin
i3:=jsr75i.read_byte;
PutInt(i2,i,i3);

if (i3>4) then
if (i3<11) then
if i3<>7 then begin
if i3>8 then i3:=8;
SetArr(i3);
for i4:=0 to 14 do
if GetInt(i4,0)=0 then begin
PutInt(i4,0,i*mapx+i2);
byte:=jsr75i.read_byte; //сколько байтов в объекте
for i3:=1 to byte do PutInt(i4,i3,jsr75i.read_byte);
SetArr(1);
break;
end;
end;

end;

texts:=0;

SetArr(2);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do
for i2:=0 to mapx+1 do
PutInt(i2,i,0);
repeat
i3:=jsr75i.read_byte;
if i3<>255 then begin
i4:=jsr75i.read_byte;
byte:=jsr75i.read_byte;
PutInt(i3,i4,byte);
if byte=5 then begin //текст
ntext[texts]:=i4*mapx+i3;
texts:=texts+1;
end;
end;
else break;
until false;

//загрузка текстов
if texts>0 then begin
test:=jsr75i.get_stream;
for i:=1 to texts do begin
tgame[i-1]:=win2utf(readline(test));
tauthor[i-1]:=win2utf(readline(test));
tauthor[i-1]:=copy(tauthor[i-1],0,length(tauthor[i-1])-1);
end;
closeResource(test);
end;
i:=close_file(path);
end;
//курсор
ex:=0;
ey:=0;
end;

//возврат  в редактор
ReloadMap;
allmapx:=(mapx+1)*tsize-w;
allmapy:=(mapy+1)*tsize-h;
if ex>mapx then ex:=0;
if ey>mapy then ey:=0;
efill:=false; //режим заливки
elink:=false; //режим привязки
eok:=true; //возможность ставить тайлы
come:=2;
ledit:=1;
{repeat
key2:=GetKeyClicked;
key:=GetKeyPressed;
Delay(delayfps);
until (key2=0) and (key=0);}
repeat
//камера
if dmx[1]<>ex*tsize+tsize/2-w2 then
begin
dmx[1]:=ex*tsize+tsize/2-w2;
if dmx[1]>allmapx then dmx[1]:=allmapx;
if dmx[1]<0 then dmx[1]:=0;
end;
if dmy[1]<>ey*tsize-h2 then
begin
dmy[1]:=ey*tsize-h2;
if dmy[1]>allmapy then dmy[1]:=allmapy;
if dmy[1]<0 then dmy[1]:=0;
end;
//отрисовка
SetColor(255,255,255);
FillRect(0,0,w,h);
dmy[3]:=dmy[1]/tsize;
dmx[3]:=dmx[1]/tsize;
dmx[2]:=dmx[3]+wt;
dmy[2]:=dmy[3]+ht;
if dmy[2]>mapy then dmy[2]:=mapy;
if dmx[2]>mapx then dmx[2]:=mapx;
for i3:=0 to 1 do begin
SetArr(i3);
for i:=dmy[3] to dmy[2] do begin
for i2:=dmx[3] to dmx[2] do begin
i4:=GetInt(i2,i);
if i4<>0 then drawImage(tile[layer[i3]+i4],i2*tsize-dmx[1],i*tsize-dmy[1]);
end;
end;
end;
SetArr(2);
for i:=dmy[3] to dmy[2] do begin
for i2:=dmx[3] to dmx[2] do begin
i4:=GetInt(i2,i);
if (i4<>0) and (i4<20) then
drawImage(tile[layer[2]+i4],i2*tsize-dmx[1],i*tsize-dmy[1]);
end;
end;

//редактор
DrawImage(tile[layer[er]+elar[er]],ex*tsize-dmx[1],ey*tsize-dmy[1]);
SetColor(0,0,0);
if eok=false then SetColor(255,0,0);
DrawRect(ex*tsize-dmx[1]-1,ey*tsize-dmy[1]-1,tsize+1,tsize+1);

//отрисовка привязки
SetArr(1);
if elink=false then begin
i4:=GetInt(ex,ey);
if i4=6 then begin
SetColor(255,0,255);
//if elink then SetColor(125,0,125);
SetArr(i4);
for i:=0 to 4 do if GetInt(i,0)=ey*mapx+ex then break;
if i<5 then begin
i2:=GetInt(i,2);
i3:=GetInt(i,3);
if (i2<>0) and (i3<>0) then
DrawLine(ex*tsize+tsize/2-dmx[1],ey*tsize+tsize/2-dmy[1],
i2*tsize+tsize/2-dmx[1],i3*tsize+tsize/2-dmy[1]);
end;
end;
end;
//режим привязки
if elink then begin
elar[er]:=0;

SetColor(125,0,125);
SetArr(elm);
for i:=0 to 14 do if GetInt(i,0)=ely*mapx+elx then break;
if i<15 then begin
i2:=GetInt(i,2);
i3:=GetInt(i,3);
if (i2<>0) and (i3<>0) then
DrawLine(elx*tsize+tsize/2-dmx[1],ely*tsize+tsize/2-dmy[1],
i2*tsize+tsize/2-dmx[1],i3*tsize+tsize/2-dmy[1]);
end;

SetColor(255,0,255);
DrawLine(elx*tsize+tsize/2-dmx[1],ely*tsize+tsize/2-dmy[1],
ex*tsize+tsize/2-dmx[1],ey*tsize+tsize/2-dmy[1]);
key2:=GetKeyClicked;

if (keyToAction(key2)=GA_FIRE) then begin
SetArr(1);
i2:=GetInt(ex,ey);
if i2=5 then begin
SetArr(elm);
for i:=0 to 14 do if GetInt(i,0)=ely*mapx+elx then break;
//пишем данные
if i<15 then begin
SetArr(elm);
PutInt(i,1,i2);
PutInt(i,2,ex);
PutInt(i,3,ey);
end;
elink:=false;
elar[er]:=elm;
end;
else eok:=false;
end;

if key2=rsoft then elink:=false;
end;
else begin
//режим заливки
if efill then begin
i:=efx*tsize-dmx[1];
i2:=efy*tsize-dmy[1];
i3:=ex*tsize-efx*tsize+tsize;
i4:=ey*tsize-efy*tsize+tsize;
if ex<efx then begin
i:=ex*tsize-dmx[1];
i3:=efx*tsize-ex*tsize+tsize;
end;
if ey<efy then begin
i2:=ey*tsize-dmy[1];
i4:=efy*tsize-ey*tsize+tsize;
end;
SetColor(0,0,0);
DrawRect(i-1,i2-1,i3+1,i4+1);
if keyToAction(key2)=GA_FIRE then begin
tmp[0]:=ex;
tmp[1]:=ey;
if tmp[0]>efx then begin
tmp[0]:=efx;
efx:=ex;
end;
if tmp[1]>efy then begin
tmp[1]:=efy;
efy:=ey;
end;
for i4:=tmp[1] to efy do begin
for i3:=tmp[0] to efx do begin
eok:=true;
if elar[er]=0 then SetDeletes else SetAdds;
if eok then begin
SetArr(er);
PutInt(i3,i4,elar[er]);
end;
end;
end;
efill:=false;
end;
if key2=-8 then begin
tmp[0]:=ex;
tmp[1]:=ey;
if tmp[0]>efx then begin
tmp[0]:=efx;
efx:=ex;
end;
if tmp[1]>efy then begin
tmp[1]:=efy;
efy:=ey;
end;
for i4:=tmp[1] to efy do begin
for i3:=tmp[0] to efx do begin
SetDeletes;
SetArr(er);
PutInt(i3,i4,0);
end;
end;
efill:=false;
end;
end;

//управление
key2:=GetKeyClicked;
if key2=KE_KEY0 then begin //тест карты
//SaveMap;
//i:=open_file(path);
//test:=jsr75i.get_stream;
come:=0;
ledit:=2;
spawnx:=0;
spawny:=0;
TestMap;
if (x=0) and (y=0) then begin
x:=ex*tsize+tsize/2-plw/2;
y:=ey*tsize;
end;
Game;
end;
//выбор тайла
if (key2=KE_KEY1) then begin
elar[er]:=elar[er]-1;
if elar[0]<0 then elar[0]:=5;
if elar[1]<0 then elar[1]:=10;
if elar[2]<0 then elar[2]:=5;
end;
if (key2=KE_KEY3) then begin
elar[er]:=elar[er]+1;
if elar[0]>5 then elar[0]:=0;
if elar[1]>10 then elar[1]:=0;
if elar[2]>5 then elar[2]:=0;
end;

if (key2=KE_KEY7) then begin //заливка
efx:=ex;
efy:=ey;
if efill=false then efill:=true else efill:=false;
end;
if (key2=KE_KEY9) then begin //пипетка
SetArr(er);
elar[er]:=GetInt(ex,ey);
end;
//if (key2=KE_POUND) then SetTile; //параметры объектов
if (key2=KE_POUND) then if (er<2) then er:=er+1 else er:=0; //смена слоя
if (key2=KE_STAR) then if (er>0) then er:=er-1 else er:=2;

if (keyToAction(key2)=GA_FIRE) and (efill=false) then begin
eok:=true; //ставим тайл
if elar[er]=0 then SetDeletes else SetAdds;
if eok then begin
SetArr(er);
PutInt(ex,ey,elar[er]);
end;
end;

if (key2=-8) and (efill=false) then begin //удаление
SetDeletes;
SetArr(er);
PutInt(ex,ey,0);
end;
if key2=rsoft then Game; //выход в меню

end; //недоступно в режиме привязки

if key2=lsoft then begin //сохранение карты
if (name='') or (name='.lvl') or (path='/') then begin
DrawText('Неверный путь сохранения.',w/10,h-ha-5);
repaint;
Delay(1000);
end;
else begin
SaveMap;
end;
end;
key:=GetKeyPressed;
i:=get_key_states;
if keyToAction(key2)=GA_RIGHT then ex:=ex+1;
if keyToAction(key2)=GA_LEFT then ex:=ex-1;
if keyToAction(key2)=GA_UP then ey:=ey-1;
if keyToAction(key2)=GA_DOWN then ey:=ey+1;
if (i and 32>0) and (key=KE_KEY6) then ex:=ex+1;
if (i and 4>0) and (key=KE_KEY4) then ex:=ex-1;
if (i and 2>0) and (key=KE_KEY2) then ey:=ey-1;
if (i and 64>0) and (key=KE_KEY8) then ey:=ey+1;
if ex<0 then ex:=0;
if ey<0 then ey:=0;
if ex>mapx then ex:=mapx;
if ey>mapy then ey:=mapy;
SetColor(0,0,0);
drawtext(''+er+'|'+elar[er],1,0);
drawtext('x: '+ex,1,ha);
drawtext('y: '+ey,1,ha*2);
SetArr(er);
drawtext(''+GetInt(ex,ey),1,ha*3);
fps;
repaint;
Delay(delayfps);
until false;
end;


///////////////////////
////////Менюшки////////
///////////////////////
procedure LevelProp;
begin
if come<>1 then pos:=1;
come:=1;
bt[2]:=false;
dmx[1]:=0;
dmy[1]:=0;
tmp[0]:=w-getImageWidth(menubg);
tmp[1]:=h-getImageHeight(menubg);
if mapx<3 then mapx:=10;
if mapy<3 then mapy:=10;
// Заполняем названия пунктов меню
tmenu[1]:='Путь: '+path;
tmenu[2]:='Ширина: '+mapx;
tmenu[3]:='Высота: '+mapy;
tmenu[4]:='Создать';
tmenu[5]:='Продолжить';
tmenu[6]:='Назад';
repeat
BasicMenu(6);
if key2=GA_FIRE then begin
if pos=1 then Manager;
if (pos=2) or (pos=3) then begin
if pos=2 then click:=mapx;
if pos=3 then click:=mapy;
showTextBox('Введите число',''+click,3,TF_NUMERIC);
con:=createCommand('ОК',CM_OK, 1);
cback:=createCommand('Назад',CM_BACK, 2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
click:=stringToInteger(getTextBoxString);
if pos=2 then mapx:=click;
if pos=3 then mapy:=click;
end;
showCanvas;
LevelProp;
end;
if (pos=4) then begin
if (mapx>2) and (mapy>2) and (mapx<256) and (mapy<256)
and (name<>'') and (name<>'.lvl') then begin
ledit:=0;
LevelEditor;
end;
end;
if (pos=5) and ((layers<>0) or (ledit=1)) then begin
ledit:=2;
LevelEditor;
end;
end;
until (key2=GA_FIRE) and (pos=6);
Game;
end;


procedure Mods;
begin //список модов
pos:=0;
stemp:='Не выбрано|';
test:=openResource('/modlist');
if (resourceAvailable(test)) then begin
i2:=stringtointeger(readLine(test));
for i:=1 to i2 do stemp:=stemp+readLine(test)+'|';
closeResource(test);
end;
stemp:=stemp+'Назад';
parse2(stemp,'|');
dmy[0]:=h2-(getsize(0)+1)*ha/2;
if dmy[0]<h/20+ha2 then dmy[0]:=h/20+ha2;
repeat
BasicMenu2(getsize(0)-1);
if keyToAction(key2)=GA_FIRE then begin
if (pos<>getsize(0)-1) then begin
modset:=getitem(0,pos);
come:=4;
if pos=0 then begin
modset:='';
GameLoader;
end;
ModLoader;
Game;
end;
end;
until (pos=getsize(0)-1) and (keyToAction(key2)=GA_FIRE);
end;


procedure SetKeys;
begin
if come=0 then pos:=1;
come:=1;
tmenu[1]:='Левый софт: '+lsoft;
tmenu[2]:='Правый софт: '+rsoft;
tmenu[3]:='Джост вверх: '+k_up;
tmenu[4]:='Джост вниз: '+k_down;
tmenu[5]:='Джост влево: '+k_left;
tmenu[6]:='Джост вправо: '+k_right;
tmenu[7]:='Назад';
repeat
BasicMenu(7);
if key2=GA_FIRE then begin
if (pos=1) or (pos=2) then begin
stemp:='Нажмите любую клавишу';
Format;
repeat
key2:=GetKeyClicked;
SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
for i:=0 to max do DrawText(getitem(2,i),
w2-getStringWidth(getitem(2,i))/2,h2-ha*(-i-1));
repaint;
Delay(20);
until key2<>0;
if pos=1 then lsoft:=key2;
if pos=2 then rsoft:=key2;
if pos=3 then k_up:=key2;
if pos=4 then k_down:=key2;
if pos=5 then k_left:=key2;
if pos=6 then k_right:=key2;
byte:=1;
SetKeys;
end;
end;
until (key2=GA_FIRE) and (pos=7);
come:=0;
end;


procedure Settings2;
begin
if come=0 then pos:=1;
come:=1;
tmenu[1]:='Настройка клавиш';
tmenu[2]:='Прозрачность окон: '+awind;
tmenu[3]:='Моды';
tmenu[4]:='Сброс';
tmenu[5]:='Назад';
repeat
BasicMenu(5);
if key2=GA_LEFT then begin
if (pos=2) then byte:=1;
if pos=2 then begin
if awind=125 then awind:=0 else
if awind=255 then awind:=125;
end;
Settings2;
end;
if key2=GA_RIGHT then begin
if (pos=2) then byte:=1;
if pos=2 then begin
if awind=125 then awind:=255 else
if awind=0 then awind:=125;
end;
Settings2;
end;
if key2=GA_FIRE then begin
if pos=1 then begin
come:=0;
SetKeys;
Settings2;
end;
if pos=3 then begin
Mods;
Settings2;
end;
if pos=4 then begin
deleteRecordStore('Data');
GameLoader;
Settings2;
end;
end;
until (key2=GA_FIRE) and (pos=5);
if byte=1 then begin
CreateImage(w,hd);
for i:=0 to 4 do dialogbg[i]:=SetOpaque(GetImage,awind/5*(i+1));
end;
come:=0;
end;


procedure Settings;
begin
if come=0 then pos:=1;
come:=1;
// Заполняем названия пунктов меню
tmenu[1]:='Музыка: '+music;
tmenu[2]:='Тип управления: '+keystype;
tmenu[3]:='Графика: ';
tmenu[4]:='Сенсор: ';
tmenu[5]:='Прочее';
tmenu[6]:='Назад';
if ts then tmenu[4]:=tmenu[4]+'вкл'
else tmenu[4]:=tmenu[4]+'выкл';
if graphic=0 then tmenu[3]:=tmenu[3]+'высоко';
if graphic=1 then tmenu[3]:=tmenu[3]+'низко';
repeat
BasicMenu(6);
//изменение настроек
if key2=GA_LEFT then begin
if pos<5 then byte:=1;
if pos=1 then begin
if music=1 then stopPlayer;
music:=0;
end;
if pos=2 then begin
keystype:=keystype-1;
if keystype=1 then begin
k_up:=KeyToAction(KE_KEY2);
k_down:=KeyToAction(KE_KEY8);
k_left:=KeyToAction(KE_KEY4);
k_right:=KeyToAction(KE_KEY6);
end;
if keystype<1 then keystype:=1;
end;
if pos=3 then graphic:=1;
if pos=4 then ts:=false;
Settings;
end;
if key2=GA_RIGHT then begin
if pos<5 then byte:=1;
if pos=1 then begin
if music=0 then begin
if not openPlayer('/main.mid','audio/midi') then delay(1);
if not setPlayerCount(1) then delay(1);
if not startPlayer then delay(1);
music:=1;
end;
end;
if pos=2 then begin
keystype:=keystype+1;
if keystype=2 then begin
k_up:=-1;
k_down:=-2;
k_left:=-3;
k_right:=-4;
ts:=false;
end;
if keystype>2 then keystype:=2;
end;
if pos=3 then graphic:=0;
if pos=4 then begin
keystype:=1;
ts:=true;
end;
Settings;
end;
if key2=GA_FIRE then begin
if pos=5 then begin
come:=0;
Settings2;
Settings;
end;
end;
until (key2=GA_FIRE) and (pos=6);
if byte=1 then begin
rms:=OpenRecordStore('Data');
ModifyRecordStoreEntry(rms,''+music,5);
ModifyRecordStoreEntry(rms,''+graphic,6);
ModifyRecordStoreEntry(rms,''+keystype,7);
ModifyRecordStoreEntry(rms,''+awind,8);
ModifyRecordStoreEntry(rms,''+lsoft,9);
ModifyRecordStoreEntry(rms,''+rsoft,10);
ModifyRecordStoreEntry(rms,''+k_up,11);
ModifyRecordStoreEntry(rms,''+k_down,12);
ModifyRecordStoreEntry(rms,''+k_left,13);
ModifyRecordStoreEntry(rms,''+k_right,14);
if ts then touch:=1 else touch:=0;
ModifyRecordStoreEntry(rms,''+touch,15);
closeRecordStore(rms);
byte:=0;
end;
Game;
end;


procedure Help;
begin
come:=5;
pos:=0;
dmy[0]:=0;
repeat
fps;
SetColor(255,255,255);
FillRect(0,0,w,h);
if pos*ha+dmy[0]<h/20+ha2 then dmy[0]:=dmy[0]+ha/2;
if pos*ha+dmy[0]>h-ha*3 then dmy[0]:=dmy[0]-ha/2;
key2:=GetKeyClicked;
if keyToAction(key2)=GA_UP then
if pos<1 then pos:=im2 else pos:=pos-1;
if keyToAction(key2)=GA_DOWN then
if pos>im2-1 then pos:=0 else pos:=pos+1;
//рисуем каждый элемент меню
for im:=0-dmy[0]/ha to h/ha+1-dmy[0]/ha do begin
if (touch=0) and (TouchText(5,im*ha+dmy[0],2)) then begin
key2:=KE_KEY5;
pos:=im;
end;
if im<>pos then begin
//если он не выбран
SetColor(0,0,0);
DrawText(getitem(2,im),5,im*ha+dmy[0]);
end;
else begin
//если пункт меню выбран
SetColor(0,0,0);
FillRect(0,im*ha+dmy[0],
getStringWidth(getitem(2,im))+10,ha);
SetColor(255,255,255);
DrawText(getitem(2,im),5,im*ha+dmy[0]);
end;
end;
touch:=pointer_state;
SetColor(255,255,255);
FillRect(0,0,w,h/20+ha2);
setFont(0,1,16);
SetColor(0,0,0);
DrawText(tmenu[0],w2-getStringWidth(tmenu[0])/2,h/20);
setFont(0,0,8);
repaint;
delay(delayfps);

if keyToAction(key2)=GA_FIRE then
if pos=im2 then Game;

until false
end;


procedure Info;
begin
pos:=1;
come:=1;
tmenu[0]:='Библиотека';
tmenu[1]:='Об игре';
tmenu[2]:='О редакторе';
tmenu[3]:='Об авторе';
tmenu[4]:='Обучение';
tmenu[5]:='Оф. страница';
tmenu[6]:='Назад';
if h>200 then menubg:=loadImage('/img/author.png');
menubits:=false;
repeat
BasicMenu(6);
if key2=GA_FIRE then begin
if pos<4 then begin
txt:=openResource('/help/'+pos+'.txt');
s:='';
SetColor(255,255,255);
FillRect(0,0,w,h);
repeat
stemp:=win2utf(readLine(txt));
if stemp<>'-' then s:=s+stemp+' \' else break;
until false;
closeResource(txt);
stemp:=s+' ';
Format;
im2:=max;
setitem(2,im2-1,'----------');
setitem(2,im2,tmenu[6]);
Help;
end;
if pos=4 then begin
ledit:=4;
come:=0;
test:=openResource('/maps/tng/test'+keystype+'.lvl');
Game;
end;
if pos=5 then i:=platform_request('http://'+url+'/portal/');
if pos=6 then begin
if h>200 then menubg:=loadImage('/img/menu.png');
menubits:=true;
Game;
end;
end;
until false;
end;


procedure MapList;
begin
if come<>4 then pos:=0;
come:=4;
s:='';
for i:=1 to clvl+1 do s:=s+'Тест '+i+'|';
s:=s+'Назад';
parse2(s,'|');
dmy[0]:=h2-(getsize(0)+1)*ha/2;
if dmy[0]<h/20+ha2 then dmy[0]:=h/20+ha2;
repeat
BasicMenu2(clvl+1);
if keyToAction(key2)=GA_FIRE then begin
if (pos<>clvl+1) then begin
map:=pos;
come:=0;
Game;
end;
if pos=clvl+1 then begin
Game;
end;
end;
until false;
end;


procedure OnlineMapList;
begin
tmenu[1]:='';
come:=4;
bt[2]:=false;
i2:=1;
dmx[1]:=0;
dmy[1]:=0;
tmp[0]:=w-getImageWidth(menubg);
tmp[1]:=h-getImageHeight(menubg);
SetColor(0,0,0);
if ledit<>3 then begin //выход в кеш списка
if not OpenHttp(conn,'http://'+url+'/levels3.php?page='+(page+1)+chr(38)+'sort='+sort) then
begin
DrawText('Нет соединения :(',w/10,h-ha-5);
repaint;
Delay(1000);
come:=4;
Game;
end;
else begin
DrawText('Загрузка...',w/10,h-ha-5);
repaint;
//Delay(1000);
SetHttpMethod(conn,GET);
AddHttpHeader(conn,'UA','NamoOnline');
i:=SendHttpMessage(conn); //считываем код соединения
if i<>200 then tmenu[1]:='Ошибка '+i; //Если была ошибка, выводим об этом сообщение
//если не было ошибки, считываем ответ сервера
if tmenu[1]='' then tmenu[1]:=GetHttpResponse(conn);
closeHttp(conn);
Parse2(tmenu[1]+'Сортировка: '+sort+'\Страница: '+(page+1)+'\Назад','\');
end;
end;
pos:=0;
ledit:=0;
dmy[0]:=h2-(getsize(0)+1)*ha/2;
if dmy[0]<h/20+ha2 then dmy[0]:=h/20+ha2;
repeat
BasicMenu2(getsize(0)-1);
if (pos>getsize(0)-4) then
begin
if keyToAction(key2)=GA_LEFT then begin
if pos=getsize(0)-3 then begin
if sort='name' then sort:='date'
else if sort='rate' then sort:='name'
else if sort='date' then sort:='rate'
OnlineMapList;
end;
if (pos=getsize(0)-2) and (page>0) then begin
page:=page-1;
OnlineMapList;
end;
end;
if keyToAction(key2)=GA_RIGHT then begin
if pos=getsize(0)-3 then begin
if sort='name' then sort:='rate'
else if sort='rate' then sort:='date'
else if sort='date' then sort:='name';
OnlineMapList;
end;
if (pos=getsize(0)-2) and (getsize(0)>12) then begin
page:=page+1;
OnlineMapList;
end;
end;
end;
if (keyToAction(key2)=GA_FIRE) then begin
if (pos<getsize(0)-3) then
begin
SetColor(0,0,0);
if not OpenHttp(conn,'http://'+url+'/load2.php?fl='+getitem(0,pos))
then begin
DrawText('Ошибка соединения :(',w/10,h-ha-5);
repaint;
Delay(1000);
end;
else begin
DrawText('Загрузка...',w/10,h-ha-5);
repaint;
//Delay(1000);
SetHttpMethod(conn,GET);
AddHttpHeader(conn,'UA','NamoOnline');
i:=SendHttpMessage(conn); //считываем код соединения
closeHttp(conn);
end;
//i:=platform_request('http://'+url+'/lvl/'+getitem(0,pos));
connect.connect('http://'+url+'/lvl/'+getitem(0,pos));
i:=connect.createb;
connect.writeb;
DownloadMap;
ledit:=3;
come:=0;
Game;
end;
if (pos=getsize(0)-2) then
begin
showTextBox('Страница',''+(page+1),3,TF_NUMERIC);
con:=createCommand('ОК',CM_OK,1);
cback:=createCommand('Назад',CM_BACK, 2);
addCommand(con);
addCommand(cback);
repaint;
repeat
clicked:=getClickedCommand;
delay(100);
until clicked<>emptyCommand;
if clicked=con then begin
if page>0 then page:=stringToInteger(getTextBoxString)-1;
end;
showCanvas;
OnlineMapList;
end;
end;
until (keyToAction(key2)=GA_FIRE) and (pos=getsize(0)-1);
Game;
end;


procedure GameMenu;
begin
come:=0;
if clvl=0 then pos:=2 else pos:=1;
// Заполняем названия пунктов меню
tmenu[1]:='Продолжить';
tmenu[2]:='Новая игра';
tmenu[3]:='Список карт';
tmenu[4]:='Онлайн-список';
tmenu[5]:='Назад';
repeat
BasicMenu(5);
if key2=GA_FIRE then begin
ledit:=0;
if pos=1 then begin
map:=clvl;
Game;
end;
if pos=2 then begin
map:=0;
Game;
end;
if (pos=3) then begin
MapList;
end;
if pos=4 then begin
OnlineMapList;
end;
if pos=6 then begin
Mods;
end;
if pos=5 then begin
come:=1;
Game;
end;
end;
until false;
end;

procedure Menu;
begin
bt[2]:=false;
menubits:=true;
dmx[1]:=0;
dmy[1]:=0;
come:=0;
if yousure=false then pos:=1;
tmp[0]:=w-getImageWidth(menubg);
tmp[1]:=h-getImageHeight(menubg);
// Заполняем названия пунктов меню
tmenu[0]:='Portal Mobile';
tmenu[1]:='Игра';
tmenu[2]:='Редактор карт';
tmenu[3]:='Настройки';
tmenu[4]:='Инфо';
tmenu[5]:='Выход';
repeat
BasicMenu(5);
if key2=GA_FIRE then
begin
if pos<>5 then yousure:=false;
if pos = 1 then GameMenu;
if pos = 2 then LevelProp;
if pos = 3 then Settings;
if pos = 4 then Info;
if pos = 5 then begin
if yousure then Exit;
tmenu[5]:=tmenu[5]+'?';
yousure:=true;
end;
end;
until false;
end;


///////////////////////
////////Печеньки///////
///////////////////////
procedure CurrentLevel;
begin
test:=openResource('/maps/test'+map+'.lvl');
if not (resourceAvailable(test)) then begin
DrawText('test'+map+'.lvl не найден',w/10,h-ha-5);
repaint;
Delay(1000);
if map=0 then Exit;
map:=0;
CurrentLevel;
end;
if clvl<map then begin
SetColor(255,255,255);
FillRect(0,0,w,h);
end;
SetColor(0,0,0);
DrawText('Загрузка...',w/10,h-ha-5);
repaint;
if clvl<map then begin
clvl:=map;
rms:=OpenRecordStore('Data');
ModifyRecordStoreEntry(rms,''+clvl,4);
closeRecordStore(rms);
end;
end;


procedure MapLoader;
begin
mapx:=readByte(test);
mapy:=readByte(test);
layers:=readByte(test);
ArraysReset;

if (layers<>5) and (layers<>51) then begin
SetColor(255,255,255);
FillRect(0,0,w,h);
SetColor(0,0,0);
DrawText('Карта не поддерживается',w/10,h-ha-5);
repaint;
closeResource(test);
Delay(1000);
come:=4;
Game;
end;
else begin //загрузка карты
SetArr(0);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do
PutInt(i2,i,readByte(test));

SetArr(1);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do PutInt(mapx+1,i,0);
for i2:=0 to mapx+1 do PutInt(i2,mapy+1,0);
for i:=0 to mapy do
for i2:=0 to mapx do
begin
i3:=readByte(test);
PutInt(i2,i,i3);

if (i3>4) then
if (i3<11) then
if i3<>7 then begin
if i3>8 then i3:=8;
SetArr(i3);
for i4:=0 to 4 do
if GetInt(i4,0)=0 then begin
PutInt(i4,0,i*mapx+i2);
byte:=readByte(test); //сколько байтов в объекте
for i3:=1 to byte do PutInt(i4,i3,readByte(test));
SetArr(1);
break;
end;
end;

end;

texts:=0;

SetArr(2);
i:=Dim(mapx+2,mapy+2);
for i:=0 to mapy+1 do
for i2:=0 to mapx+1 do
PutInt(i2,i,0);
repeat
i3:=readByte(test);
if i3<>-1 then begin
i4:=readByte(test);
byte:=readByte(test);
PutInt(i3,i4,byte);
if byte=5 then begin //текст
ntext[texts]:=i4*mapx+i3;
texts:=texts+1;
end;
end;
else break;
until false;

//загрузка текстов
if texts>0 then begin
for i:=1 to texts do begin
tgame[i-1]:=win2utf(readline(test));
tauthor[i-1]:=win2utf(readline(test));
tauthor[i-1]:=copy(tauthor[i-1],0,length(tauthor[i-1])-1);
end;
end;


end;
closeResource(test);
MapOptimize;
TestMap;
end;


procedure DrawMap;
begin
if (graphic=1) then begin
SetColor(198,203,206);
FillRect(0,0,w,h);
end; //wt+1
dmy[3]:=dmy[1]/tsize;
dmx[3]:=dmx[1]/tsize;
if dmy[3]<0 then dmy[3]:=0;
if dmx[3]<0 then dmx[3]:=0;
dmx[2]:=dmx[3]+wt;
dmy[2]:=dmy[3]+ht;
if dmy[2]>mapy then dmy[2]:=mapy;
if dmx[2]>mapx then dmx[2]:=mapx;
if graphic=0 then begin
SetArr(0);
i4:=layer[1]-1;
for i:=dmy[3] to dmy[2] do begin
for i2:=dmx[3] to dmx[2] do begin
i3:=GetInt(i2,i);
if i3<>i4 then drawImage(tile[i3],i2*tsize-dmx[1],i*tsize-dmy[1]);
end;
end;
end;


if izometry then begin
SetArr(1);
for i:=dmy[2] downto dmy[3] do
for i2:=dmx[2] downto dmx[3] do begin
i3:=GetInt(i2,i);
if i3<>0 then drawImage(tile[layer[1]+i3],i2*tsize-dmx[1]-tsize/4,i*tsize-dmy[1]-tsize/4);
end;
end;

end;


procedure DrawMap2;
begin
if izometry=false then begin
SetArr(1);
for i:=dmy[3] to dmy[2] do
for i2:=dmx[3] to dmx[2] do begin
i3:=GetInt(i2,i);
if i3>0 then drawImage(tile[layer[1]+i3],i2*tsize-dmx[1],i*tsize-dmy[1]);
end;
end;

end;


function Block(sx,sy: real): boolean;
begin
tx:=trunc(sx)/tsize;
ty:=trunc(sy)/tsize;
sb:=GetInt(tx,ty);
if (sb>0) and (sb<3) then Block:=true;
//if (sb>3) then begin
//end;
end;


procedure Scripts;
begin
SetArr(2); //проверка на цельные блоки
scx:=trunc(x+iner)/tsize;
scy:=trunc(y+usk)/tsize;
i:=GetInt(scx,scy);
if i<2 then begin
scx:=trunc(x+plw+iner-1)/tsize;
scy:=trunc(y+usk)/tsize;
i:=GetInt(scx,scy);
end;
if i<2 then begin
scx:=trunc(x+iner)/tsize;
scy:=trunc(y+tsize+usk-1)/tsize;
i:=GetInt(scx,scy);
end;
if i<2 then begin
scx:=trunc(x+plw+iner-1)/tsize;
scy:=trunc(y+tsize+usk-1)/tsize;
i:=GetInt(scx,scy);
end;

if i>1 then begin
if i=2 then begin //выход
spawnx:=0;
spawny:=0;
scy2:=0;
scx2:=0;
if ledit=2 then begin
ReloadMap;
LevelEditor;
end;
if ledit=3 then OnlineMapList;
if ledit=4 then Info;
map:=map+1;
if map>maps then map:=0;
Game;
end;
if i=3 then begin //смерть
SetColor(255,255,255);
FillRect(0,0,w,h);
repaint;
ReloadMap;
for i3:=0 to 5 do begin
key2:=GetKeyClicked;
if key2=rsoft then begin
if ledit=2 then LevelEditor;
Menu;
end;
Delay(10);
end;
TestMap;
end;
if i=4 then begin //чекпоинт
spawnx:=scx*tsize+tsize/2-plw/2;
spawny:=scy*tsize;
end;
if i=5 then begin //текст
//if viewtext=0 then begin
txs:=0; //первая строка текста
albg:=0;
viewtext:=1;
for i:=0 to texts do begin
if (scy*mapx+scx)=ntext[i] then ctext:=i;
end;
//end;
PutInt(scx,scy,-5);
end;

end;
if i=layer[3] then begin //дверь
if (x+iner>scx*tsize) and (x-plw<scx*tsize) then begin
x:=scx*tsize;
iner:=0;
end;
if (x+plw+iner<(scx+1)*tsize) and (x-plw>scx*tsize) then begin
x:=(scx+1)*tsize-plw;
iner:=0;
end;

end;

if i=layer[3]+1 then begin //поле
if (x+iner>scx*tsize) and (x-plw<scx*tsize) then begin
vr[1]:=0;
vr[2]:=0;
end;
if (x+plw+iner<(scx+1)*tsize) and (x-plw>scx*tsize) then begin
vr[1]:=0;
vr[2]:=0;
end;

end;

if (i>layer[3]+1) and (i<layer[3]+5) then begin //панели веры
i4:=0; //проверяем какая платформа и столкновение с ней
if (i=layer[3]+2) and (y+usk>scy*tsize-2)
and (y+usk<(scy+1)*tsize) then i4:=1; //вверх

if i4=0 then if (i=layer[3]+3) then if (x+plw+iner>(scx+1)*tsize-2)
and (x+plw+iner<(scx+2)*tsize) then i4:=2; //влево

if i4=0 then if (i=layer[3]+4) then if (x+plw+iner>scx*tsize)
and (x+iner<scx*tsize+2) then i4:=3; //вправо


if i4<>0 then begin
SetArr(8);
for i2:=0 to 14 do if GetInt(i2,0)=scy*mapx+scx then break;
if i2<15 then begin
i3:=GetInt(i2,2); //iner
i2:=GetInt(i2,1); //usk
if (i2<>0) or (i3<>0) then begin
if i3>100 then i3:=-(i3-100);
if i2>100 then i2:=-(i2-100);
if i4=1 then begin
y:=scy*tsize-4;
if i2<>0 then usk:=-abs(i2);
if i3<>0 then iner:=i3;
end;
if (i4=2) or (i4=3) then begin
if i4=2 then begin
x:=(scx+1)*tsize-4;
if i3<>0 then iner:=-abs(i3);
end;
if i4=3 then begin
x:=scx*tsize+4;
if i3<>0 then iner:=abs(i3);
end;
if i2<>0 then usk:=-i2;
end;
anim:=true;
scx2:=scx;
scy2:=scy;
if i4=1 then begin
if i3>0 then i3:=1;
if i3<0 then i3:=2;
end;
else i3:=0;
if i4=2 then begin
if i2>0 then i3:=2;
if i2<0 then i3:=1;
end;
if i4=3 then begin
if i2>0 then i3:=2;
if i2<0 then i3:=1;
end;
anim1:=layer[3]+3+3*i3+(i4-1)*9;
anim2:=layer[3]+5+3*i3+(i4-1)*9;
end;
SetArr(1);
end;
end;
end;

end;


procedure Objects;
begin
//SetArr(1);
//ручная кнопка
if (i=6) or (i=layer[3]+3) then begin
if i=6 then PutInt(scx,scy,layer[3]+3);
if i=layer[3]+3 then PutInt(scx,scy,6);
SetArr(6); //массив кнопок (i)
for i2:=0 to 14 do if GetInt(i2,0)=scy*mapx+scx then break;
if i2<15 then begin //если кнопка существует
//GetInt(i2,0) - x*y кнопки
//GetInt(i2,1) - номер типа завис. объекта (его гл. массива)
//GetInt(i2,2) - x объекта
//GetInt(i2,3) - y объекта
//GetInt(i2,4) - действие
byte:=GetInt(i2,3)*mapx+GetInt(i2,2);
SetArr(GetInt(i2,1));
for i3:=0 to 14 do if GetInt(i3,0)=byte then break;
if i3<15 then begin //если дверь существует
//можем почитать данные двери или вообще к ней не обращатся
//GetInt(i3,1-4)
i4:=GetInt(i3,0); //x*y двери
SetArr(2);
PutInt(i4 mod mapx,i4/mapx,-GetInt(i4 mod mapx,i4/mapx));
//активация анимации
anim:=true;
scx2:=i4 mod mapx;
scy2:=i4/mapx;
SetArr(1);
//anim1:=GetInt(scx2,scy2);
if GetInt(scx2,scy2)=layer[3]+2 then begin
anim1:=layer[3]+2;
anim2:=layer[3];
end;
else begin
anim1:=layer[3];
anim2:=layer[3]+2;
end;
//SetArr(1);
//PutInt(i4 mod mapx,i4/mapx,layer[3]+2); //выпиливаем дверь
end;
end;

end;
//else if i=layer[3]+3 then PutInt(scx,scy,6);

end;


procedure Phys;
begin
usk:=usk+0.45;
if not (Block(x,y+plh) or Block(x+plw-1,y+plh)
or (y+plh>(mapy+1)*tsize)) then begin
if iner>=0.1 then iner:=iner-0.1;
if iner<=-0.1 then iner:=iner+0.1;
if (iner>-0.1) and (iner<0.1) then iner:=0;
end;
if usk>15 then usk:=15;
if usk<-15 then usk:=-15;
if iner>15 then iner:=15;
if iner<-15 then iner:=-15;
SetArr(1);
if (Block(x,y+plh+usk) or Block(x+plw-1,y+plh+usk)
or (y+plh+usk-1>(mapy+1)*tsize)) then begin //низ (пол)
//убираем инерцию
if iner>=0.5 then iner:=iner-0.5;
if iner<=-0.5 then iner:=iner+0.5;
if (iner>-0.5) and (iner<0.5) then iner:=0;
y:=ty*tsize-plh;
if trunc(usk)<>0 then usk:=0;
end;

if jump=1 then begin
usk:=usk-jspeed;
jump:=0;
end;

if y-1+usk<0 then begin
y:=0;
if trunc(usk)<>0 then usk:=0;
end;
if (Block(x,y-1+usk) or Block(x+plw-1,y-1+usk)) then
begin //вверх
y:=(ty+1)*tsize;
if trunc(usk)<>0 then usk:=0;
end;

if x+plw+iner>(mapx+1)*tsize then begin
x:=(mapx+1)*tsize-plw;
iner:=0;
end;
if (Block(x+plw+iner-1,y+plh-1) or Block(x+plw+iner-1,y+1)) then
begin //справа
x:=tx*tsize-plw;
if trunc(iner)<>0 then iner:=0;
end;

if x+iner<0 then begin
x:=0;
iner:=0;
end;
if (Block(x-1+iner,y+plh-1) or Block(x-1+iner,y+1)) then
begin //слева
x:=(tx+1)*tsize;
if trunc(iner)<>0 then iner:=0;
end;

end;


procedure Camera;
begin
if (mapx<wt) then begin
dmx[1]:=-(w2-mapx*tsize/2)+tsize/2;
SetColor(255,255,255);
FillRect(0,0,w,h);
end; //wt+1
else begin
if dmx[1]<>x-w2+7+iner then begin
dmx[1]:=trunc(x+iner)-w2+7;
if dmx[1]>allmapx then dmx[1]:=allmapx;
if dmx[1]<0 then dmx[1]:=0;
end;
end;
if (mapy<ht) then begin
dmy[1]:=-(h2-mapy*tsize/2)+tsize/2;
SetColor(255,255,255);
FillRect(0,0,w,h);
end;
else begin
if dmy[1]<>y-h2+usk then begin
dmy[1]:=trunc(y+usk)-h2;
if dmy[1]>allmapy then dmy[1]:=allmapy;
if dmy[1]<0 then dmy[1]:=0;
end;
end;
x:=x+iner;
y:=y+usk;
end;


///////////////////////
////////Порталы////////
///////////////////////
procedure PortalPhys;
begin
i:=i+1; //портал вылет
i2:=1; //портал в котором игрок
if i=3 then begin
i:=1;
i2:=2;
end;
jump:=0;
if vr[i]=1 then begin
x:=px[i]+tsize/2-plw/2;
y:=py[i]-plh;
end;
if vr[i]=2 then begin
x:=px[i]+1;
y:=py[i];
end;
if vr[i]=3 then begin
x:=px[i]+tsize/2-plw/2;
y:=py[i]+1;
end;
if vr[i]=4 then begin
x:=px[i]-plw;
y:=py[i];
end;

//изменение анимации
if vr[i]=2 then vcr:=0;
if vr[i]=4 then vcr:=vcr2;
// Трансмутация физики

if (vr[i]=1) and (vr[i2]=1) or ((vr[i]=1) and (vr[i2]=3)) then begin
usk:=-usk;
if usk>-5 then usk:=-5;
end;

if (vr[i]=3) and ((vr[i2]=2) or (vr[i2]=4)) then begin
if usk<0 then usk:=0;
end;

if (vr[i]=3) and (vr[i2]=3) then usk:=-usk;
if (vr[i]=1) and ((vr[i2]=2) or (vr[i2]=4)) then begin
iner:=0;
if usk>-5 then usk:=-5;
end;

if ((vr[i]=4) and (vr[i2]=1)) or ((vr[i]=2) and (vr[i2]=3)) then begin
iner:=-usk;
usk:=0;
end;
if ((vr[i]=2) and (vr[i2]=1)) or ((vr[i]=4) and (vr[i2]=3)) then begin
iner:=usk;
usk:=0;
end;

if ((vr[i]=2) and (vr[i2]=2)) then begin
iner:=-iner;
if iner<2 then iner:=2;
end;

if ((vr[i]=4) and (vr[i2]=4)) then begin
iner:=-iner;
if iner>-2 then iner:=-2;
end;
ported:=true;
end;


procedure Reload;
begin
vr[1]:=0;
vr[2]:=0;
end;


procedure Portals;
begin
if (vr[1]<>0) and (vr[2]<>0) then begin // начало и конец действия столкновения с порталом
i2:=0;
for i:=1 to 2 do begin
if i2=0 then begin
if (vr[i]=1) then begin
if (px[i]<=x+plw-5) and (px[i]>=x-tsize+5) then begin
if (py[i]<=y+plh+usk) and (py[i]>=y+usk) then begin
PortalPhys;
end;
end;
end;
if (vr[i]=2) then begin
if (px[i]<=x+tsize+iner) and (px[i]>=x+iner) then begin
if (py[i]+1<=y+tsize/2) and (py[i]+1>=y-5) then begin
PortalPhys;
end;
end;
end;
if (vr[i]=3) then begin
if (px[i]<=x+plw-5) and (px[i]>=x-tsize+5) then begin
if (py[i]<=y+plh+usk) and (py[i]>=y+usk) then begin
PortalPhys;
end;
end;
end;
if (vr[i]=4) then begin
if (px[i]<=x+plw-1+iner) and (px[i]>=x-tsize+plw-1+iner) then begin
if (py[i]+1<=y+tsize/2) and (py[i]+1>=y-5) then begin
PortalPhys;
end;
end;
end;

end;

end;
end;

if ported then begin
Camera;
//DrawMap;
ported:=false;
end;

end;


procedure PortalsDraw;
begin
for i:=1 to 2 do
begin
if vr[i]<>0 then begin
if i=1 then setColor(255,128,0);
if i=2 then setColor(0,50,255);
//порталы
if (vr[i]=1) or (vr[i]=3) then begin
drawLine(px[i]-dmx[1],py[i]-dmy[1],px[i]+tsize-1-dmx[1],py[i]-dmy[1]);
end;
if (vr[i]=2) or (vr[i]=4) then begin
drawLine(px[i]-dmx[1],py[i]-dmy[1],px[i]-dmx[1],py[i]+tsize-1-dmy[1]);
end;
//метки
if (vr[i]=2) or (vr[i]=4) then mety[i]:=tsize;
if (vr[i]=1) or (vr[i]=3) then metx[i]:=tsize;
if (px[i]-dmx[1]+iner>w) or (px[i]+tsize-dmx[1]+iner<0)
or (py[i]-dmy[1]+usk>h) or (py[i]+tsize-dmy[1]+usk<0) then begin
metx[i]:=px[i]-dmx[1]-3+tsize/2;
mety[i]:=py[i]-dmy[1]-3+tsize/2;
if px[i]-dmx[1]>w then metx[i]:=w-3;
if py[i]-dmy[1]>h then mety[i]:=h-3;
if px[i]-dmx[1]<0 then metx[i]:=0;
if py[i]-dmy[1]<0 then mety[i]:=0;
if (metx[1]=metx[2]) and (mety[1]=mety[2]) then setColor(123,15,123);
fillRect(metx[i],mety[i],3,3);
end;
end;
end;

end;


procedure PortalBits;
begin
for i2:=1 to 2 do
begin
if i2=1 then setColor(255,128,0);
if i2=2 then setColor(0,50,255);
BitsBoom;
if (px[i2]-dmx[1]>-tsize) and (px[i2]-dmx[1]<w+tsize) and
(py[i2]-dmy[1]>-tsize) and (py[i2]-dmy[1]<h+tsize) then
begin
Bits(px[i2],py[i2],vr[i2]);
end;
end;

end;


procedure PortalShoot;
begin
if (pox<>0) or (poy<>0) then begin
if pwall=0 then begin
if r=1 then setColor(255,128,0);
if r=2 then setColor(0,50,255);
spx[r]:=trunc(x)+5;
spy[r]:=trunc(y)+9;
pwall:=r;
if keystype=1 then r:=0;
if keystype=2 then begin
r:=r+1;
if r=3 then r:=1;
end;
tmp[1]:=px[1];
tmp[2]:=py[1];
tmp[3]:=px[2];
tmp[4]:=py[2];
tmp[0]:=vr[1];
tmp[5]:=vr[2];
spx[pwall]:=spx[pwall]-pox;
spy[pwall]:=spy[pwall]-poy;
end;
if pwall<>0 then begin
if pwall=1 then setColor(255,128,0);
if pwall=2 then setColor(0,50,255);
spx[pwall]:=spx[pwall]+pox;
spy[pwall]:=spy[pwall]+poy;

//столкновение выстрела
SetArr(1);
for i:=0 to shoot do begin
ix:=trunc(spx[pwall]+cos(toRadians(ang))*i);
iy:=trunc(spy[pwall]+sin(toRadians(ang))*i);
//нельзя поставить
if GetInt(ix/tsize,iy/tsize)>0 then begin
if GetInt(ix/tsize,iy/tsize)<3 then break
else begin
if (GetInt(ix/tsize,iy/tsize)=5) then break;
if (GetInt(ix/tsize,iy/tsize)=7) then break;
end;
end;
if (iy>(mapy+1)*tsize) or (iy<0)
or (ix>(mapx+1)*tsize) or (ix<0) then begin
pwall:=0;
break;
end;
end;

if pwall<>0 then begin
SetArr(1);
i:=GetInt(ix/tsize,iy/tsize);

if Block(ix,iy) and
(i<>2) and (i<>5) and (i<>7) then begin
if vr[0]=0 then begin
pox:=ix mod tsize;
poy:=iy mod tsize;
//ВВЕРХ ВЛЕВО ВНИЗ ВПРАВО
pox:=pox-pox/shoot;
poy:=poy-pox/shoot;
//запоминаем старые данные
vr[pwall]:=0;
//проверяем диагональную стрельбу
SetArr(1);
if (tx>0) and (ty>0) and (tx<mapx+1) and (ty<mapy+1) then begin
if (poy=0) and (GetInt(tx,ty-1)=0) then vr[pwall]:=1;
if (pox=tsize-1) and (GetInt(tx+1,ty)=0) then vr[pwall]:=2;
if (poy=tsize-1) and (GetInt(tx,ty+1)=0) then vr[pwall]:=3;
if (pox=0) and (GetInt(tx-1,ty)=0) then vr[pwall]:=4;
end;
else begin
if (ty=mapy+1) and (GetInt(tx,mapy)=0) then vr[pwall]:=1;
if (tx=0) and (GetInt(1,ty)=0) then vr[pwall]:=2;
if (ty=0) and (GetInt(tx,1)=0) then vr[pwall]:=3;
if (tx=mapx+1) and (GetInt(mapx,ty)=0) then vr[pwall]:=4;
end;
end;
else vr[pwall]:=vr[0];
//начальные координаты линии портала
if vr[pwall]=1 then begin
px[pwall]:=tx*tsize;
py[pwall]:=ty*tsize-1;
end;
if vr[pwall]=2 then begin
px[pwall]:=(tx+1)*tsize;
py[pwall]:=ty*tsize;
end;
if vr[pwall]=3 then begin
px[pwall]:=tx*tsize;
py[pwall]:=(ty+1)*tsize;
end;
if vr[pwall]=4 then begin
px[pwall]:=tx*tsize-1;
py[pwall]:=ty*tsize;
end;

if (vr[pwall]=0) or
((vr[1]=vr[2]) and (px[1]=px[2]) and (py[1]=py[2]) and (px[1]<>0) and (px[2]<>0))
then begin
vr[1]:=tmp[0];
px[1]:=tmp[1];
py[1]:=tmp[2];
vr[2]:=tmp[5];
px[2]:=tmp[3];
py[2]:=tmp[4];
end;
else begin
bt[2]:=false; //пересоздание порталов
i2:=pwall;
Bits(px[pwall],py[pwall],vr[pwall]);
end;
pox:=0;
poy:=0;
pwall:=0;
vr[0]:=0;
end;
else begin //если на стене нельзя поставить портал
SetArr(1);
i:=GetInt(ix/tsize,iy/tsize);
if (i=2) or (i=5) or (i=7) then begin
pox:=0;
poy:=0;
if pwall=2 then i3:=6 else i3:=4;
//разлетающиеся частицы
for i:=0 to 10 do begin
bit[i3,i]:=ix;
bit[i3+1,i]:=iy;
end;
bt[pwall-1]:=true;
pwall:=0;
vr[0]:=0;
end;
else begin //если не попал
fillRect(spx[pwall]-dmx[1]-1,spy[pwall]-dmy[1]-1,3,3);
end;
end;
end;
else begin //если за границами карты
pox:=0;
poy:=0;
vr[0]:=0;
end;
ix:=0;
iy:=0;
end;

end;
end;


procedure Keys; //общее
begin
if key=rsoft then begin
if ledit=2 then LevelEditor;
if ledit=3 then OnlineMapList;
if ledit=4 then Info;
Menu;
end;
if key=lsoft then begin
if (vr[2]=0) and (vr[1]<>0) then r:=2;
aimmode:=true;
if keystype=2 then ang:=ang2;
end;

if key=KE_KEY0 then Reload;

if (keyToAction(key)=GA_FIRE) then begin
SetArr(1);
scx:=trunc(x+iner)/tsize;
scy:=trunc(y+1+usk)/tsize;
i:=GetInt(scx,scy);
if i<2 then begin
scx:=trunc(x+plw+iner-1)/tsize;
scy:=trunc(y+1+usk)/tsize;
i:=GetInt(scx,scy);
end;
if i>1 then Objects;
end;
if (keyToAction(key)=k_down) or (key=k_down) then begin
if viewtext=2 then viewtext:=3
else begin
if (viewtext=3) and (txs+hd/ha<max) then begin
txs:=txs+hd/ha; //нач строка
txx:=0;txy:=0;
viewtext:=2;
end;
else viewtext:=0;
end;
end;

if (k and 32>0) then begin //вправо
if (Block(x,y+plh+usk) or Block(x+plw-1,y+plh+usk)
or (y+plh+usk>(mapy+1)*tsize)) then begin
if (iner>=0) and (iner<4) then iner:=iner+1;
if (iner<=0) then iner:=iner+1;
end;
else begin
if (iner>=0) and (iner<4) then iner:=iner+0.5;
if (iner<=0) then iner:=iner+0.5;
end;
end;

if (k and 4>0) then begin //влево
if (Block(x,y+plh+usk) or Block(x+plw-1,y+plh+usk)
or (y+plh+usk>(mapy+1)*tsize)) then begin
if (iner<=0) and (iner>-4) then iner:=iner-1;
if (iner>=0) then iner:=iner-1;
end;
else begin
if (iner<=0) and (iner>-4) then iner:=iner-0.5;
if (iner>=0) then iner:=iner-0.5;
end;
end;

if (k and 2>0) then begin //прыжок
if (keystype=1) or (GetKeyPressed<>KE_KEY2) then begin
if (usk=0) then
if (Block(x,y+plh) or Block(x+plw-1,y+plh)) then jump:=1;
end;
end;
if dbg=1 then //полет
if (k and 64>0) then usk:=usk-1;
end;


procedure TouchScreen;
begin
SetColor(0,0,0);
if (r<>0) or viewmode or aimmode then begin
dmy[0]:=bh*2+5;
for i:=0 to 2 do DrawImage(sbutt,bh*2*i+5*(i+1),h-bh*2-5);
FillTriangle(bh+6,h-bh-6,bh*2+6,h-bh-6,bh+6,h-bh*2-6); //downs
FillTriangle(bh*5+14,h-bh-6,bh*4+14,h-bh-6,bh*5+14,h-bh*2-6);
FillTriangle(bh*2+10,h-bh*2+bh/2-5,bh*3+10,h-bh/2-6,bh*4+10,h-bh*2+bh/2-5); //down
end;
else dmy[0]:=0;
for i:=0 to 1 do DrawImage(sbutt,bh*4*i+10*i+5,h-bh*4-10-dmy[0]);
DrawImage(sbutt,bh*2+10,h-bh*4-10-dmy[0]); //up
for i:=0 to 2 do DrawImage(sbutt,bh*2*i+5*(i+1),h-bh*2-5-dmy[0]);
DrawImage(sbutt,w-bh*2-5,h-bh*4-10); //menu
for i:=0 to 1 do DrawImage(sbutt,w-bh*2*(i+1)-5*(i+1),h-bh*2-5);
for i:=0 to 1 do drawRoundRect(w-bh*2+1+i,h-bh*2-3,bh*2-13,bh*2-5,5,5); //portals
FillTriangle(bh+5,h-bh*3-10-dmy[0],bh+5,h-bh*2-10-dmy[0],bh*2+5,h-bh*3-10-dmy[0]); //ups
FillTriangle(bh*5+15,h-bh*3-10-dmy[0],bh*4+15,h-bh*3-10-dmy[0],bh*5+15,h-bh*2-10-dmy[0]);
FillTriangle(bh*2+10,h-bh*2-bh/2-10-dmy[0],bh*3+10,
h-bh*3-bh/2-10-dmy[0],bh*4+10,h-bh*2-bh/2-10-dmy[0]); //up
FillTriangle(bh/2+5,h-bh-5-dmy[0],bh+bh/2+5,h-bh*2-5-dmy[0],bh+bh/2+5,h-5-dmy[0]); //left
FillTriangle(bh*6-bh/2+15,h-bh-5-dmy[0],bh*5-bh/2+15,
h-bh*2-5-dmy[0],bh*5-bh/2+15,h-5-dmy[0]); //right
DrawRect(bh*2+10+bh/2,h-bh-bh/2-6-dmy[0],bh,bh);
FillRect(bh*2+10+bh/2,h-bh-bh/2-5-dmy[0],bh,bh);
if (r=0) or aimmode then begin
if (k=0) then begin //джост
if touch=0 then begin //aim
ox:=pointer_pressed_x;
oy:=pointer_pressed_y;
if pointer_state=1 then
if (ox>trunc(x)-dmx[1]) and (oy<trunc(y)-dmy[1]+plh) then
if (ox<trunc(x)-dmx[1]+plw) and (oy>trunc(y)-dmy[1]) then 
if aimmode=false then begin
if (vr[2]=0) and (vr[1]<>0) then r:=2;
aimmode:=true;
if keystype=2 then ang:=ang2;
end;
else begin
aimmode:=false;
r:=0;
end;
end;
if TButton(5,h-bh*4-10-dmy[0]) then k:=6; //1..6
if TButton(bh*2+10,h-bh*4-10-dmy[0]) then k:=2;
if TButton(bh*4+15,h-bh*4-10-dmy[0]) then k:=34;
if TButton(5,h-bh*2-5-dmy[0]) then k:=4;
if TButton(bh*2+10,h-bh*2-5-dmy[0]) and (touch=0) then key:=KE_KEY5;
if TButton(bh*4+15,h-bh*2-5-dmy[0]) then k:=32;

if TButton(w-bh*2-5,h-bh*4-10) then //menu
if aimmode then Reload else key:=rsoft;
if TButton(w-bh*2-5,h-bh*2-5) and (touch=0) then //portals
if viewmode=false then
if aimmode then begin
if r=1 then r:=2 else r:=1;
end;
else r:=1;
if TButton(w-bh*4-10,h-bh*2-5) and (touch=0) then //view
if viewmode then viewmode:=false else viewmode:=true;
if (viewmode=false) and (aimmode=false) then Keys else begin //доп к режиму просмотра
if TButton(5,h-bh*2-5) then k:=68;
if TButton(bh*2+10,h-bh*2-5) then k:=64;
if TButton(bh*4+15,h-bh*2-5) then k:=96;
end;

end;
end;
else begin //стрельба
if (pox=0) and (poy=0) then begin
if r=1 then setColor(255,128,0);
if r=2 then setColor(0,50,255);
if r<>0 then drawRect(0,0,w-1,h-1);
ang:=-1;
if touch=0 then begin
if TButton(5,h-bh*4-10-dmy[0]) then ang:=225; //1..9
if TButton(bh*2+10,h-bh*4-10-dmy[0]) then begin
ang:=270;vr[0]:=3;
end;
if TButton(bh*4+15,h-bh*4-10-dmy[0]) then ang:=315;
if TButton(5,h-bh*2-5-dmy[0]) then begin
ang:=180;vr[0]:=2;
end;
if TButton(bh*2+10,h-bh*2-5-dmy[0]) then Reload;
if TButton(bh*4+15,h-bh*2-5-dmy[0]) then begin
ang:=0;vr[0]:=4;
end;
if TButton(5,h-bh*2-5) then ang:=135;
if TButton(bh*2+10,h-bh*2-5) then begin
ang:=90;vr[0]:=1;
end;
if TButton(bh*4+15,h-bh*2-5) then ang:=45;
if TButton(w-bh*4-10,h-bh*2-5) then
if r=1 then r:=2 else r:=1;
if TButton(w-bh*2-5,h-bh*2-5) then r:=0;
if TButton(w-bh*2-5,h-bh*4-10) then begin
if ledit=2 then LevelEditor;
if ledit=3 then OnlineMapList;
if ledit=4 then Info;
Menu;
end;

end;
if (ang<>-1) then begin
pox:=trunc(cos(toRadians(ang))*shoot);
poy:=trunc(sin(toRadians(ang))*shoot);
end;


end;
end;
touch:=pointer_state;
end;


procedure View;
begin //режим просмотра карты
viewmode:=true;
repeat
if (mapx<wt) then begin
dmx[1]:=-(w2-mapx*tsize/2)+tsize/2;
SetColor(255,255,255);
FillRect(0,0,w,h);
end; //wt+1
else begin
if dmx[1]<0 then dmx[1]:=0;
if dmx[1]>allmapx then dmx[1]:=allmapx;
end;

if (mapy<ht) then begin
dmy[1]:=-(h2-mapy*tsize/2)+tsize/2;
SetColor(255,255,255);
FillRect(0,0,w,h);
end;
else begin
if dmy[1]<0 then dmy[1]:=0;
if dmy[1]>allmapy then dmy[1]:=allmapy;
end;


DrawMap;
if aimmode then begin
if r=1 then setColor(255,128,0);
if r=2 then setColor(0,50,255);
DrawLine(trunc(x)+5-dmx[1],trunc(y)+9-dmy[1],ix-dmx[1],iy-dmy[1]);
end;
drawImage(chell[cr+vcr],trunc(x)-dmx[1]-sipl[cr],trunc(y)-dmy[1]);

if (pox<>0) or (poy<>0) then begin
if pwall<>0 then begin
if pwall=1 then setColor(255,128,0);
if pwall=2 then setColor(0,50,255);
SetArr(1);
fillRect(spx[pwall]-1-dmx[1],spy[pwall]-1-dmy[1],3,3);
end;
end;
//частицы
if vr[1]<>0 then begin
setColor(255,128,0);
for i:=0 to 10 do Plot(bit[0,i]-dmx[1],bit[1,i]-dmy[1]);
end;
if vr[2]<>0 then begin
setColor(0,50,255);
for i:=0 to 10 do Plot(bit[2,i]-dmx[1],bit[3,i]-dmy[1]);
end;

//ложное открытие частиц
if (bt[0]) then begin
setColor(255,128,0);
for i:=0 to 10 do Plot(bit[4,i]-dmx[1],bit[5,i]-dmy[1]);
end;
if (bt[1]) then begin
setColor(0,50,255);
for i:=0 to 10 do Plot(bit[6,i]-dmx[1],bit[7,i]-dmy[1]);
end;

DrawMap2;
PortalsDraw;
k:=get_key_states;
if ts then TouchScreen;
if (k and 32>0) then dmx[1]:=dmx[1]+8;
if (k and 4>0) then dmx[1]:=dmx[1]-8;
if (k and 2>0) then dmy[1]:=dmy[1]-8;
if (k and 64>0) then dmy[1]:=dmy[1]+8;
setColor(255,255,255);
drawRect(0,0,w-1,h-1);
fps;
repaint;
Delay(delayfps);
key:=GetKeyClicked;
if (key=KE_KEY7) or (key=KE_POUND) or
(key=lsoft) or (key=rsoft) then viewmode:=false;
until viewmode=false;
end;


procedure Aim;
begin //режим точного прицеливания
if (pox=0) and (poy=0) then begin
if r=0 then r:=1;
if r=1 then setColor(255,128,0);
if r=2 then setColor(0,50,255);
SetArr(1);
for i:=0 to w2/tsize do
begin
ix:=trunc(cos(toRadians(ang))*tsize*i+x+5);
iy:=trunc(sin(toRadians(ang))*tsize*i+y+9);
if (ix<=0) or (ix>(mapx+1)*tsize) or (iy<=0) or (iy>(mapy+1)*tsize) then break;
else if Block(ix,iy) then break;
end;

DrawLine(trunc(x)-dmx[1]+5,trunc(y)-dmy[1]+9,
trunc(cos(toRadians(ang))*tsize*i+trunc(x)-dmx[1]+5),
trunc(sin(toRadians(ang))*tsize*i+trunc(y)-dmy[1]+9));
if touch=0 then k:=get_key_states;
if touch=0 then key:=GetKeyClicked;
if (k and 2>0) then begin
if sng>0 then sng:=0;
ang:=ang+sng/5-1;
sng:=sng-1;
if sng<-25 then sng:=-25;
end;
if (k and 64>0) then begin
if sng<0 then sng:=0;
ang:=ang+sng/5+1;
sng:=sng+1;
if sng>25 then sng:=25;
end;
if k=0 then sng:=0;
if keyToAction(key)=GA_LEFT then begin
//ang:=ang+180;
end;
if keyToAction(key)=GA_RIGHT then begin
//ang:=ang+180;
end;
if key=KE_STAR then begin
if r=1 then r:=2 else r:=1;
end;
if (keystype=1) and (key=KE_KEY7) then begin
ix:=trunc(cos(toRadians(ang))*tsize*i+x+5);
iy:=trunc(sin(toRadians(ang))*tsize*i+y+9);
View;
end;
if key=KE_POUND then begin
if keystype=1 then begin
if r=2 then r:=1 else r:=2;
end;
else begin
ix:=trunc(cos(toRadians(ang))*tsize*i+x+5);
iy:=trunc(sin(toRadians(ang))*tsize*i+y+9);
View;
end;
end;
if key=KE_KEY0 then Reload;
if (key=lsoft) or (key=rsoft) then begin
if keystype=1 then r:=0;
aimmode:=false;
end;
if (keyToAction(key)=GA_FIRE) and (pointer_state=0) then begin
aimmode:=false;
ang2:=ang;
pox:=trunc(cos(toRadians(ang))*shoot);
poy:=trunc(sin(toRadians(ang))*shoot);
end;

end;
end;


procedure Text;
begin //вывод диалогов
if viewtext<>0 then begin

if ts then begin
if touch=0 then begin
oy:=pointer_pressed_y;
if pointer_state=1 then begin
if (oy<hd) then key:=k_down;
Keys;
end;
end;
//touch:=pointer_state;
end;


//просто показ текста
if viewtext=3 then begin
SetColor(255,255,255);
DrawImage(dialogbg[albg],0,0);
SetColor(0,0,0);
DrawLine(0,hd,w,hd);
for i:=0 to hd/ha-1 do begin
DrawText(getitem(2,i+txs),0,i*ha);
end;
FillRect(w-wat,hd-ha,wat,ha);
SetColor(255,255,255);
DrawText(tauthor[ctext],w-wat,hd-ha);
end;

//анимация текста
if viewtext=2 then begin
DrawImage(dialogbg[albg],0,0);
for i:=0 to txy do begin
SetColor(0,0,0);
if txy=i then begin
DrawText(copy(getitem(2,i+txs),0,txx),0,i*ha);
end;
else DrawText(getitem(2,i+txs),0,i*ha);
end;
if txx<length(getitem(2,i-1+txs))-1 then txx:=txx+1
else if (txy<max) and (txy<hd/ha-1) then begin
txy:=txy+1;
txx:=0;
end;
else viewtext:=3;
SetColor(0,0,0);
DrawLine(-1,hd,w/4*albg-1,hd);
FillRect(w-wat,hd-ha,wat,ha);
SetColor(255,255,255);
DrawText(tauthor[ctext],w-wat,hd-ha);
end;

//анимация появления
if viewtext=1 then begin
DrawImage(dialogbg[albg],0,0);
if albg<4 then albg:=albg+1;
else begin
txx:=0;txy:=0;
wat:=getStringWidth(tauthor[ctext]);
viewtext:=2;
stemp:=tgame[ctext];
Format;
end;
SetColor(0,0,0);
DrawLine(-1,hd,w/4*albg-1,hd);
end;

end;
end;


procedure PortalKeys;
begin
if key=KE_KEY1 then ang:=225;
if key=KE_KEY3 then ang:=315;
if key=KE_KEY7 then ang:=135;
if key=KE_KEY9 then ang:=45;
end;


procedure Keys1;
begin
if (r=0) then begin
k:=get_key_states;
key:=GetKeyClicked;
key2:=GetKeyPressed;
if key2=KE_KEY1 then k:=6;
if key2=KE_KEY3 then k:=34;
Keys;
if key=KE_KEY7 then View;
if key=KE_KEY9 then paused:=true;
if key=KE_STAR then r:=1;
if key=KE_POUND then r:=2;
end;
else begin //Портал-режим
if (pox=0) and (poy=0) then begin
key:=key2;
key2:=GetKeyPressed;
if r=1 then setColor(255,128,0);
if r=2 then setColor(0,50,255);
if r<>0 then drawRect(0,0,w-1,h-1);
ang:=-1;
if key2=0 then begin
if GetKeyClicked<>0 then begin
if (key=KE_STAR) then if (r=1) then r:=0 else r:=1;
if (key=KE_POUND) then if (r=2) then r:=0 else r:=2;
end;
PortalKeys;
if (keyToAction(key)=GA_UP) then begin
ang:=270;vr[0]:=3;
end;
if (keyToAction(key)=GA_LEFT) then begin
ang:=180;vr[0]:=2;
end;
if (keyToAction(key)=GA_RIGHT) then begin
ang:=0;vr[0]:=4;
end;
if (keyToAction(key)=GA_DOWN) then begin
ang:=90;vr[0]:=1;
end;
if ang<>-1 then begin
pox:=trunc(cos(toRadians(ang))*shoot);
poy:=trunc(sin(toRadians(ang))*shoot);
end;
key:=0;
end;

end;
end;

end;


procedure Keys2;
begin
k:=get_key_states;
key:=GetKeyClicked;
Keys;
if key=KE_STAR then if r=1 then r:=2 else r:=1;
if key=KE_POUND then View;
if r=1 then setColor(255,128,0);
if r=2 then setColor(0,50,255);
if r<>0 then fillRect(2,h-ha*2,ha,ha);
setColor(0,0,0);
if r<>0 then drawRect(2,h-ha*2,ha,ha);
if (pox=0) and (poy=0) then begin
ang:=-1;
//Считываем отпускания клавиш
PortalKeys;
if key=KE_KEY2 then begin
ang:=270;vr[0]:=3;
end;
if key=KE_KEY4 then begin
ang:=180;vr[0]:=2;
end;
if key=KE_KEY6 then begin
ang:=0;vr[0]:=4
end;
if key=KE_KEY8 then begin
ang:=90;vr[0]:=1;
end;

if ang<>-1 then begin
ang2:=ang;
pox:=trunc(cos(toRadians(ang))*shoot);
poy:=trunc(sin(toRadians(ang))*shoot);
end;

end;

end;


procedure Animation;
begin
if anim then begin //анимация объектов
if anim1<anim2 then anim1:=anim1+1;
if anim1>anim2 then anim1:=anim1-1;

if anim1=anim2 then begin

if anim1=layer[3] then begin
anim1:=5;
anim2:=anim1;
end;

for i2:=0 to 2 do
for i:=0 to 2 do begin
if (anim1=layer[3]+3+i*3+i2*9) then begin
anim1:=8+i2;
anim2:=anim1;
end;
if anim1=layer[3]+5+i*3+i2*9 then anim2:=layer[3]+3+i*3+i2*9;
end;

end;

SetArr(1);
PutInt(scx2,scy2,anim1);
if anim1=anim2 then anim:=false;
end;

//анимация игрока
//бег вправо
if (k and 32>0) or (key2=KE_KEY3) then begin
if not (k and 4>0) then vcr:=0;
if cr<runcr[0] then cr:=runcr[0];
tcr:=tcr+1;
if tcr>2 then begin
cr:=cr+1;
tcr:=0;
end;
if cr>runcr[1] then cr:=runcr[0];
end;

//бег влево
if (k and 4>0) or (key2=KE_KEY1) then begin
if not (k and 32>0) then vcr:=vcr2;
if cr<runcr[0] then cr:=runcr[0];
tcr:=tcr+1;
if tcr>2 then begin
cr:=cr+1;
tcr:=0;
end;
if cr>runcr[1] then cr:=runcr[0];
end;

if iner<>0 then begin //торможение
if not (k and 4>0) and not (k and 32>0) or
(k and 4>0) and (k and 32>0) then begin
if cr<dragcr[0] then cr:=dragcr[0];
tcr:=tcr+1;
if tcr>2 then begin
cr:=cr+1;
tcr:=0;
end;
if cr>dragcr[1] then cr:=dragcr[0];
//cr:=7;
end;
end;

SetArr(1); //статика
if (Block(x,y+plh+usk) or Block(x+plw-1,y+plh+usk)
or (y+plh+usk-1>(mapy+1)*tsize)) then begin
if ((trunc(iner)=0) and (trunc(usk)=0)) then begin
tcr:=tcr+1;
if tcr>2 then begin
cr:=cr+1;
tcr:=0;
end;
if cr>stopcr[1] then cr:=stopcr[0];
end;

end;
else begin
if usk<-1 then begin //прыжок
if cr<upcr[0] then cr:=upcr[0];
tcr:=tcr+1;
if tcr>2 then begin
cr:=cr+1;
tcr:=0;
end;
if cr>upcr[1] then cr:=upcr[0];
end;

if (usk>-2) and (usk<2) then begin //полет
if cr<aircr[0] then cr:=aircr[0];
tcr:=tcr+1;
if tcr>2 then begin
cr:=cr+1;
tcr:=0;
end;
if cr>aircr[1] then cr:=aircr[0];
end;

if usk>1 then begin //падение
if cr<downcr[0] then cr:=downcr[0];
tcr:=tcr+1;
if tcr>2 then begin
cr:=cr+1;
tcr:=0;
end;
if cr>downcr[1] then cr:=downcr[0];
end;

end;

end;


procedure Game;
begin
if come=1 then Menu;
if come=2 then LevelProp;
if come=3 then LevelEditor;
if come=4 then GameMenu;
if come=5 then Info;
if (music=1) then begin
music:=2;
stopPlayer;
if not openPlayer('/game1.mid','audio/midi') then delay(1);
if not setPlayerCount(1) then delay(1);
if not startPlayer then delay(1);
end;
if ledit<2 then begin
CurrentLevel; //выбирается уровень
MapLoader; //загрузка карты
end;
if ledit=4 then MapLoader;
repeat
if IsMidletPaused then paused:=true;
if paused then Pause;
Portals; //Портация
Phys; //Столкновение
Scripts; //Триггеры
Camera; //Камера
DrawMap; //Отрисовка
if aimmode then Aim;
Animation; //Игрока
//drawImage(chell[0],trunc(x)-dmx[1],trunc(y)-dmy[1]);
drawImage(chell[cr+vcr],trunc(x)-dmx[1]-sipl[cr],trunc(y)-dmy[1]);
PortalShoot; //Выстрел
PortalBits; //Частицы
DrawMap2;
PortalsDraw; //Отрисовка
Text; //Диалоги
if aimmode=false then
if keystype=1 then Keys1 else Keys2;
if ts then TouchScreen;
if viewmode then View;
fps; //FPS
repaint;
Delay(delayfps);
until false;
end;

begin //запуск
setClip(0,0,w,h); //область отрисовки
sensor.init; //сенсор
Arrays; //дин. массивы чисел
Define(3); //дин. массивы строк
GameLoader; //загрузка основного
ModLoader; //поддержка модов
//MSLogo; //заставка
setFont(0,0,8);
Menu;
end. 